@nklisch/pi-enhanced 0.1.2 → 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 (236) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +3 -2
  3. package/node_modules/@nklisch/pi-clearance/README.md +10 -5
  4. package/node_modules/@nklisch/pi-clearance/docs/ARCHITECTURE.md +12 -7
  5. package/node_modules/@nklisch/pi-clearance/docs/CONFIGURATION.md +25 -35
  6. package/node_modules/@nklisch/pi-clearance/docs/DEVELOPER_GUIDE.md +30 -30
  7. package/node_modules/@nklisch/pi-clearance/docs/PACK_AUTHORING.md +5 -4
  8. package/node_modules/@nklisch/pi-clearance/docs/PRINCIPLES.md +14 -10
  9. package/node_modules/@nklisch/pi-clearance/docs/REFERENCE_PATTERNS.md +1 -1
  10. package/node_modules/@nklisch/pi-clearance/docs/REVIEWER_PROMPTS.md +12 -8
  11. package/node_modules/@nklisch/pi-clearance/docs/RULE_PACKS.md +1 -1
  12. package/node_modules/@nklisch/pi-clearance/docs/SPEC.md +7 -6
  13. package/node_modules/@nklisch/pi-clearance/docs/TUNE.md +2 -2
  14. package/node_modules/@nklisch/pi-clearance/docs/USER_GUIDE.md +7 -3
  15. package/node_modules/@nklisch/pi-clearance/docs/VISION.md +3 -3
  16. package/node_modules/@nklisch/pi-clearance/native/clearance-core.darwin-arm64.node +0 -0
  17. package/node_modules/@nklisch/pi-clearance/native/clearance-core.darwin-x64.node +0 -0
  18. package/node_modules/@nklisch/pi-clearance/native/clearance-core.linux-arm64-gnu.node +0 -0
  19. package/node_modules/@nklisch/pi-clearance/native/clearance-core.linux-x64-gnu.node +0 -0
  20. package/node_modules/@nklisch/pi-clearance/native/clearance-core.win32-arm64-msvc.node +0 -0
  21. package/node_modules/@nklisch/pi-clearance/native/clearance-core.win32-x64-msvc.node +0 -0
  22. package/node_modules/@nklisch/pi-clearance/package.json +9 -5
  23. package/node_modules/@nklisch/pi-clearance/src/config/config-command-plans.ts +79 -3
  24. package/node_modules/@nklisch/pi-clearance/src/config/config-command-writer.ts +7 -1
  25. package/node_modules/@nklisch/pi-clearance/src/config/defaults.ts +42 -0
  26. package/node_modules/@nklisch/pi-clearance/src/config/gated-tools.ts +7 -0
  27. package/node_modules/@nklisch/pi-clearance/src/config/loader.ts +7 -1
  28. package/node_modules/@nklisch/pi-clearance/src/config/pack-enablement-writer.ts +1 -0
  29. package/node_modules/@nklisch/pi-clearance/src/config/paths.ts +14 -3
  30. package/node_modules/@nklisch/pi-clearance/src/config/persistence.ts +135 -0
  31. package/node_modules/@nklisch/pi-clearance/src/config/schema.ts +74 -26
  32. package/node_modules/@nklisch/pi-clearance/src/contracts/AdversarialCase.ts +1 -1
  33. package/node_modules/@nklisch/pi-clearance/src/contracts/AdversarialCaseCategory.ts +1 -1
  34. package/node_modules/@nklisch/pi-clearance/src/contracts/AdversarialCaseExpectation.ts +1 -1
  35. package/node_modules/@nklisch/pi-clearance/src/contracts/AdversarialCaseResult.ts +1 -1
  36. package/node_modules/@nklisch/pi-clearance/src/contracts/AdversarialCaseResultOutcome.ts +1 -1
  37. package/node_modules/@nklisch/pi-clearance/src/contracts/AdversarialCaseSource.ts +1 -1
  38. package/node_modules/@nklisch/pi-clearance/src/contracts/AdversarialValidationReport.ts +1 -1
  39. package/node_modules/@nklisch/pi-clearance/src/contracts/AdversarialValidationStatus.ts +1 -1
  40. package/node_modules/@nklisch/pi-clearance/src/contracts/BashBlock.ts +1 -1
  41. package/node_modules/@nklisch/pi-clearance/src/contracts/BashCommandShape.ts +1 -1
  42. package/node_modules/@nklisch/pi-clearance/src/contracts/BashConditionalArm.ts +1 -1
  43. package/node_modules/@nklisch/pi-clearance/src/contracts/BashControlConstruct.ts +1 -1
  44. package/node_modules/@nklisch/pi-clearance/src/contracts/BashFlag.ts +1 -1
  45. package/node_modules/@nklisch/pi-clearance/src/contracts/BashForLoopKeywordSpans.ts +1 -1
  46. package/node_modules/@nklisch/pi-clearance/src/contracts/BashIteratorEntry.ts +1 -1
  47. package/node_modules/@nklisch/pi-clearance/src/contracts/BashIteratorEntryKind.ts +1 -1
  48. package/node_modules/@nklisch/pi-clearance/src/contracts/BashListOperator.ts +1 -1
  49. package/node_modules/@nklisch/pi-clearance/src/contracts/BashLoopVariableReference.ts +1 -1
  50. package/node_modules/@nklisch/pi-clearance/src/contracts/BashPathFact.ts +1 -1
  51. package/node_modules/@nklisch/pi-clearance/src/contracts/BashPathFactContext.ts +1 -1
  52. package/node_modules/@nklisch/pi-clearance/src/contracts/BashPathFactProvenance.ts +1 -1
  53. package/node_modules/@nklisch/pi-clearance/src/contracts/BashPathFactProvenanceEntry.ts +1 -1
  54. package/node_modules/@nklisch/pi-clearance/src/contracts/BashPathFacts.ts +1 -1
  55. package/node_modules/@nklisch/pi-clearance/src/contracts/BashPipeline.ts +1 -1
  56. package/node_modules/@nklisch/pi-clearance/src/contracts/BashStage.ts +1 -1
  57. package/node_modules/@nklisch/pi-clearance/src/contracts/BashStageProgram.ts +1 -1
  58. package/node_modules/@nklisch/pi-clearance/src/contracts/BlockOperator.ts +1 -1
  59. package/node_modules/@nklisch/pi-clearance/src/contracts/CapturedOutcome.ts +1 -1
  60. package/node_modules/@nklisch/pi-clearance/src/contracts/CommandFamilyKey.ts +1 -1
  61. package/node_modules/@nklisch/pi-clearance/src/contracts/CommandFamilySummary.ts +1 -1
  62. package/node_modules/@nklisch/pi-clearance/src/contracts/CompileError.ts +1 -1
  63. package/node_modules/@nklisch/pi-clearance/src/contracts/CompositionOperator.ts +1 -1
  64. package/node_modules/@nklisch/pi-clearance/src/contracts/CompoundBodyReason.ts +1 -1
  65. package/node_modules/@nklisch/pi-clearance/src/contracts/CompoundFeatureReason.ts +1 -1
  66. package/node_modules/@nklisch/pi-clearance/src/contracts/CompoundForm.ts +1 -1
  67. package/node_modules/@nklisch/pi-clearance/src/contracts/CompoundIteratorReason.ts +1 -1
  68. package/node_modules/@nklisch/pi-clearance/src/contracts/CorpusEntry.ts +1 -1
  69. package/node_modules/@nklisch/pi-clearance/src/contracts/CorpusExpectedLabel.ts +1 -1
  70. package/node_modules/@nklisch/pi-clearance/src/contracts/CorpusFidelity.ts +1 -1
  71. package/node_modules/@nklisch/pi-clearance/src/contracts/CorpusQueryModel.ts +1 -1
  72. package/node_modules/@nklisch/pi-clearance/src/contracts/CorpusQuerySummary.ts +1 -1
  73. package/node_modules/@nklisch/pi-clearance/src/contracts/CorpusQuerySummarySnapshot.ts +1 -1
  74. package/node_modules/@nklisch/pi-clearance/src/contracts/CorpusRecord.ts +1 -1
  75. package/node_modules/@nklisch/pi-clearance/src/contracts/CorpusSource.ts +1 -1
  76. package/node_modules/@nklisch/pi-clearance/src/contracts/CountByLabel.ts +1 -1
  77. package/node_modules/@nklisch/pi-clearance/src/contracts/Decision.ts +1 -1
  78. package/node_modules/@nklisch/pi-clearance/src/contracts/DecisionEffect.ts +1 -1
  79. package/node_modules/@nklisch/pi-clearance/src/contracts/DecisionProvenance.ts +1 -1
  80. package/node_modules/@nklisch/pi-clearance/src/contracts/DecisionSource.ts +1 -1
  81. package/node_modules/@nklisch/pi-clearance/src/contracts/DiagnosticSeverity.ts +1 -1
  82. package/node_modules/@nklisch/pi-clearance/src/contracts/EffectivePolicy.ts +1 -1
  83. package/node_modules/@nklisch/pi-clearance/src/contracts/EmbeddedShellProjection.ts +1 -1
  84. package/node_modules/@nklisch/pi-clearance/src/contracts/EnvironmentAssignment.ts +1 -1
  85. package/node_modules/@nklisch/pi-clearance/src/contracts/IteratorSourceKind.ts +1 -1
  86. package/node_modules/@nklisch/pi-clearance/src/contracts/LoopQuoteKind.ts +1 -1
  87. package/node_modules/@nklisch/pi-clearance/src/contracts/LoopVariableUnknownReason.ts +1 -1
  88. package/node_modules/@nklisch/pi-clearance/src/contracts/MatcherExpr.ts +1 -1
  89. package/node_modules/@nklisch/pi-clearance/src/contracts/MutationShapeKind.ts +1 -1
  90. package/node_modules/@nklisch/pi-clearance/src/contracts/MutationTrustBoundaryClassification.ts +1 -1
  91. package/node_modules/@nklisch/pi-clearance/src/contracts/MutationTrustBoundaryKind.ts +1 -1
  92. package/node_modules/@nklisch/pi-clearance/src/contracts/PackCompileResult.ts +1 -1
  93. package/node_modules/@nklisch/pi-clearance/src/contracts/PackWarningLevel.ts +1 -1
  94. package/node_modules/@nklisch/pi-clearance/src/contracts/ParsedEvidence.ts +1 -1
  95. package/node_modules/@nklisch/pi-clearance/src/contracts/ParsedShapeSummary.ts +1 -1
  96. package/node_modules/@nklisch/pi-clearance/src/contracts/PathAccess.ts +1 -1
  97. package/node_modules/@nklisch/pi-clearance/src/contracts/PathFactProjectScope.ts +1 -1
  98. package/node_modules/@nklisch/pi-clearance/src/contracts/PathFactsRequirement.ts +1 -1
  99. package/node_modules/@nklisch/pi-clearance/src/contracts/PathFactsResolvedConfig.ts +1 -1
  100. package/node_modules/@nklisch/pi-clearance/src/contracts/PathNormalization.ts +1 -1
  101. package/node_modules/@nklisch/pi-clearance/src/contracts/PathScope.ts +1 -1
  102. package/node_modules/@nklisch/pi-clearance/src/contracts/PathScopeMatcherExpr.ts +1 -1
  103. package/node_modules/@nklisch/pi-clearance/src/contracts/PathScopeMatcherMode.ts +1 -1
  104. package/node_modules/@nklisch/pi-clearance/src/contracts/PathUnknownReason.ts +1 -1
  105. package/node_modules/@nklisch/pi-clearance/src/contracts/PathUsageKind.ts +1 -1
  106. package/node_modules/@nklisch/pi-clearance/src/contracts/PiBuiltinToolOperation.ts +1 -1
  107. package/node_modules/@nklisch/pi-clearance/src/contracts/PiBuiltinToolPathInput.ts +1 -1
  108. package/node_modules/@nklisch/pi-clearance/src/contracts/PiBuiltinToolShape.ts +1 -1
  109. package/node_modules/@nklisch/pi-clearance/src/contracts/PiBuiltinToolSpec.ts +1 -1
  110. package/node_modules/@nklisch/pi-clearance/src/contracts/PiFileMutationToolName.ts +1 -1
  111. package/node_modules/@nklisch/pi-clearance/src/contracts/PiToolMutationFacts.ts +1 -1
  112. package/node_modules/@nklisch/pi-clearance/src/contracts/PolicyPack.ts +1 -1
  113. package/node_modules/@nklisch/pi-clearance/src/contracts/PolicyPackDocLink.ts +1 -1
  114. package/node_modules/@nklisch/pi-clearance/src/contracts/PolicyPackExample.ts +1 -1
  115. package/node_modules/@nklisch/pi-clearance/src/contracts/PolicyPackMetadata.ts +1 -1
  116. package/node_modules/@nklisch/pi-clearance/src/contracts/PolicyPackWarning.ts +1 -1
  117. package/node_modules/@nklisch/pi-clearance/src/contracts/PolicyRule.ts +1 -1
  118. package/node_modules/@nklisch/pi-clearance/src/contracts/ProposalNotRunReason.ts +1 -1
  119. package/node_modules/@nklisch/pi-clearance/src/contracts/ProposalNotRunSeverity.ts +1 -1
  120. package/node_modules/@nklisch/pi-clearance/src/contracts/QuoteKind.ts +1 -1
  121. package/node_modules/@nklisch/pi-clearance/src/contracts/Redirect.ts +1 -1
  122. package/node_modules/@nklisch/pi-clearance/src/contracts/RedirectStream.ts +1 -1
  123. package/node_modules/@nklisch/pi-clearance/src/contracts/RedirectTargetKind.ts +1 -1
  124. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayCorpus.ts +1 -1
  125. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayDelta.ts +1 -1
  126. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayDeltaBlockedSummary.ts +1 -1
  127. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayDeltaChangedRecord.ts +1 -1
  128. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayDeltaFamily.ts +1 -1
  129. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayDeltaImprovement.ts +1 -1
  130. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayDeltaRegression.ts +1 -1
  131. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayDeltaStatus.ts +1 -1
  132. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayDeltaTransitionCount.ts +1 -1
  133. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayPathFacts.ts +1 -1
  134. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayReviewerMode.ts +1 -1
  135. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayReviewerOutcome.ts +1 -1
  136. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayStatus.ts +1 -1
  137. package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayedDecision.ts +1 -1
  138. package/node_modules/@nklisch/pi-clearance/src/contracts/ShapeDiagnostic.ts +1 -1
  139. package/node_modules/@nklisch/pi-clearance/src/contracts/SourceFidelity.ts +1 -1
  140. package/node_modules/@nklisch/pi-clearance/src/contracts/SourceSpan.ts +1 -1
  141. package/node_modules/@nklisch/pi-clearance/src/contracts/Substitution.ts +1 -1
  142. package/node_modules/@nklisch/pi-clearance/src/contracts/SubstitutionKind.ts +1 -1
  143. package/node_modules/@nklisch/pi-clearance/src/contracts/ToolCallIdentity.ts +1 -1
  144. package/node_modules/@nklisch/pi-clearance/src/contracts/ToolPathAccess.ts +1 -1
  145. package/node_modules/@nklisch/pi-clearance/src/contracts/ToolPathFact.ts +1 -1
  146. package/node_modules/@nklisch/pi-clearance/src/contracts/ToolPathFactContext.ts +1 -1
  147. package/node_modules/@nklisch/pi-clearance/src/contracts/ToolPathFacts.ts +1 -1
  148. package/node_modules/@nklisch/pi-clearance/src/contracts/ToolPathUsage.ts +1 -1
  149. package/node_modules/@nklisch/pi-clearance/src/contracts/ToolShape.ts +1 -1
  150. package/node_modules/@nklisch/pi-clearance/src/contracts/UnknownPathBehavior.ts +1 -1
  151. package/node_modules/@nklisch/pi-clearance/src/contracts/UnknownToolShape.ts +1 -1
  152. package/node_modules/@nklisch/pi-clearance/src/contracts/index.ts +1 -1
  153. package/node_modules/@nklisch/pi-clearance/src/index.ts +33 -2
  154. package/node_modules/@nklisch/pi-clearance/src/native/loader.ts +29 -42
  155. package/node_modules/@nklisch/pi-clearance/src/replay/reviewer-config-proposals.ts +7 -4
  156. package/node_modules/@nklisch/pi-clearance/src/runtime/allow-request-message.ts +21 -0
  157. package/node_modules/@nklisch/pi-clearance/src/runtime/auto-reviewer-read-models.ts +165 -8
  158. package/node_modules/@nklisch/pi-clearance/src/runtime/command-registry.ts +1 -1
  159. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/allow.ts +26 -2
  160. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/packs.ts +6 -6
  161. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/scope.ts +5 -5
  162. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings/actions.ts +11 -0
  163. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings/dispatcher.ts +274 -1
  164. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings/model-options.ts +52 -0
  165. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings/native-ui.ts +54 -67
  166. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings/panels/reviewer.ts +19 -3
  167. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings/panels/scope.ts +2 -11
  168. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings/panels.ts +10 -1
  169. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings/read-model.ts +47 -13
  170. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings.ts +32 -37
  171. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/status.ts +3 -0
  172. package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/types.ts +14 -5
  173. package/node_modules/@nklisch/pi-clearance/src/runtime/handler.ts +36 -0
  174. package/node_modules/@nklisch/pi-clearance/src/runtime/mode-prompt.ts +0 -1
  175. package/node_modules/@nklisch/pi-clearance/src/runtime/model-adapter.ts +5 -1
  176. package/node_modules/@nklisch/pi-clearance/src/runtime/reviewer-context.ts +73 -10
  177. package/node_modules/@nklisch/pi-clearance/src/runtime/reviewer-prompts.ts +186 -175
  178. package/node_modules/@nklisch/pi-clearance/src/runtime/reviewer.ts +26 -6
  179. package/node_modules/@nklisch/pi-plugins/dist/infrastructure/state/local-lock-filesystem.d.ts +23 -1
  180. package/node_modules/@nklisch/pi-plugins/dist/infrastructure/state/local-lock-filesystem.js +46 -50
  181. package/node_modules/@nklisch/pi-plugins/dist/infrastructure/state/local-lock-filesystem.js.map +1 -1
  182. package/node_modules/@nklisch/pi-plugins/dist/runtime/mcp/pi-mcp-adapter-package.js +2 -2
  183. package/node_modules/@nklisch/pi-plugins/dist/runtime/mcp/pi-mcp-adapter-runtime.js +2 -2
  184. package/node_modules/@nklisch/pi-plugins/dist/runtime/subagents/pi-subagents-lifecycle.js +1 -1
  185. package/node_modules/@nklisch/pi-plugins/dist/runtime/subagents/pi-subagents-package.js +2 -2
  186. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/README.md +41 -31
  187. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/dist/public.d.ts +2 -1
  188. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/FORK-MAINTENANCE.md +17 -11
  189. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/VISION.md +14 -7
  190. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/architecture/architecture.md +11 -19
  191. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/comparison-with-upstream.md +58 -53
  192. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/package.json +2 -2
  193. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/config/agent-type-resolution.ts +43 -0
  194. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/config/agent-types.ts +11 -6
  195. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/config/custom-agents.ts +13 -6
  196. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/config/default-agents.ts +0 -52
  197. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/config/thinking-levels.ts +12 -0
  198. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/handlers/interrupt.ts +5 -2
  199. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/handlers/lifecycle.ts +3 -3
  200. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/index.ts +7 -6
  201. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/create-subagent-session.ts +7 -2
  202. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/parent-snapshot.ts +11 -3
  203. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/subagent-manager.ts +26 -56
  204. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/subagent-session.ts +48 -9
  205. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/subagent-state.ts +32 -0
  206. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/subagent.ts +105 -17
  207. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/observation/composite-subagent-observer.ts +4 -0
  208. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/observation/notification.ts +50 -46
  209. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/observation/renderer.ts +1 -1
  210. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/observation/subagent-events-observer.ts +15 -0
  211. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/runtime.ts +2 -0
  212. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/service/service-adapter.ts +35 -6
  213. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/service/service.ts +1 -0
  214. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/session/model-label.ts +19 -0
  215. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/session/prompts.ts +24 -1
  216. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/session/session-config.ts +11 -6
  217. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/settings.ts +70 -3
  218. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/tools/agent-tool.ts +27 -10
  219. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/tools/background-spawner.ts +6 -2
  220. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/tools/foreground-runner.ts +12 -3
  221. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/tools/get-result-report.ts +17 -3
  222. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/tools/get-result-tool.ts +13 -20
  223. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/tools/result-renderer.ts +6 -1
  224. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/tools/spawn-config.ts +16 -16
  225. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/tools/steer-tool.ts +12 -4
  226. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/types.ts +2 -2
  227. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/ui/agent-widget.ts +24 -11
  228. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/ui/display.ts +10 -7
  229. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/ui/glyphs.ts +7 -0
  230. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/ui/session-navigation.ts +34 -25
  231. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/ui/session-navigator.ts +30 -10
  232. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/ui/subagents-settings.ts +58 -13
  233. package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/ui/widget-renderer.ts +32 -19
  234. package/node_modules/@nklisch/pi-plugins/package.json +3 -3
  235. package/package.json +1 -1
  236. package/test/verify-bundle.mjs +28 -1
@@ -14,7 +14,6 @@
14
14
 
15
15
  import { buildSessionContext, parseSessionEntries, type SessionEntry, type ToolDefinition } from "@earendil-works/pi-coding-agent";
16
16
  import type { AgentConfigLookup } from "#src/config/agent-types";
17
- import type { EvictedSubagent } from "#src/lifecycle/subagent-manager";
18
17
  import type { SubagentStatus } from "#src/lifecycle/subagent-state";
19
18
  import type { AgentSessionEvent, SessionMessage, SubagentType } from "#src/types";
20
19
  import { formatDuration, getDisplayName } from "#src/ui/display";
@@ -26,12 +25,14 @@ export interface NavigableSubagent {
26
25
  readonly id: string;
27
26
  readonly type: SubagentType;
28
27
  readonly description: string;
28
+ readonly modelLabel: string;
29
29
  readonly status: SubagentStatus;
30
30
  readonly startedAt: number;
31
31
  readonly completedAt: number | undefined;
32
32
  readonly toolUses: number;
33
33
  readonly activeTools: ReadonlyMap<string, string>;
34
34
  readonly responseText: string;
35
+ readonly outputFile: string | undefined;
35
36
  readonly agentMessages: readonly SessionMessage[];
36
37
  isSessionReady(): boolean;
37
38
  subscribeToUpdates(fn: (event: AgentSessionEvent) => void): (() => void) | undefined;
@@ -41,17 +42,24 @@ export interface NavigableSubagent {
41
42
  /**
42
43
  * A navigable entry plus the label shown in the picker.
43
44
  *
44
- * A `live` entry sources its transcript from the in-memory record; an `evicted`
45
- * entry sources it from the persisted session file (the record is gone).
45
+ * A `live` entry sources its transcript from the in-memory session; an
46
+ * `evicted`-kind entry is a persisted snapshot for a released live session.
46
47
  */
48
+ export interface RunDisplayMetadata {
49
+ readonly modelLabel: string;
50
+ readonly startedAt: number;
51
+ readonly completedAt: () => number | undefined;
52
+ }
53
+
47
54
  export type NavigationEntry =
48
- | { readonly kind: "live"; readonly label: string; readonly record: NavigableSubagent }
49
- | { readonly kind: "evicted"; readonly label: string; readonly outputFile: string };
55
+ | { readonly kind: "live"; readonly label: string; readonly record: NavigableSubagent; readonly run: RunDisplayMetadata }
56
+ | { readonly kind: "evicted"; readonly label: string; readonly outputFile: string; readonly run: RunDisplayMetadata };
50
57
 
51
58
  /** The fields `buildLabel` reads — shared by a live record and an evicted descriptor. */
52
59
  interface LabelFields {
53
60
  readonly type: SubagentType;
54
61
  readonly description: string;
62
+ readonly modelLabel: string;
55
63
  readonly status: SubagentStatus;
56
64
  readonly startedAt: number;
57
65
  readonly completedAt: number | undefined;
@@ -77,34 +85,35 @@ export interface TranscriptSource {
77
85
  }
78
86
 
79
87
  /**
80
- * Label every navigable subagent for the picker: live records with a viewable
81
- * session, then agents evicted by the cleanup sweep (deduped against live ids).
88
+ * Label every navigable subagent: live sessions first, then persisted snapshots
89
+ * for released records and any legacy evicted descriptors.
82
90
  */
83
91
  export function listNavigableAgents(
84
92
  agents: readonly NavigableSubagent[],
85
- evicted: readonly EvictedSubagent[],
86
93
  registry: AgentConfigLookup,
87
94
  ): NavigationEntry[] {
88
- const live = agents
89
- .filter((record) => record.isSessionReady())
90
- .map((record): NavigationEntry => ({ kind: "live", record, label: buildLabel(record, registry) }));
91
- const liveIds = new Set(agents.map((record) => record.id));
92
- const evictedEntries = evicted
93
- .filter((descriptor) => !liveIds.has(descriptor.id))
94
- .map((descriptor): NavigationEntry => ({
95
- kind: "evicted",
96
- outputFile: descriptor.outputFile,
97
- label: buildLabel(descriptor, registry, true),
98
- }));
99
- return [...live, ...evictedEntries];
95
+ const live = agents.flatMap((record): NavigationEntry[] => {
96
+ const run = {
97
+ modelLabel: record.modelLabel,
98
+ startedAt: record.startedAt,
99
+ completedAt: () => record.completedAt,
100
+ };
101
+ if (record.isSessionReady()) {
102
+ return [{ kind: "live", record, label: buildLabel(record, registry), run }];
103
+ }
104
+ return record.outputFile
105
+ ? [{ kind: "evicted", outputFile: record.outputFile, label: buildLabel(record, registry, true), run }]
106
+ : [];
107
+ });
108
+ return live;
100
109
  }
101
110
 
102
111
  /**
103
112
  * Source a transcript from a persisted child-session JSONL snapshot.
104
113
  *
105
- * For an agent evicted from the manager's map by the 10-minute cleanup sweep:
106
- * the in-memory record (and its message history) is gone, but the session file
107
- * survives on disk. Reads the file, drops the `SessionHeader`, and resolves the
114
+ * For an agent whose live session was released, the in-memory message history is
115
+ * gone but the terminal record and session file survive. Reads the file, drops
116
+ * the `SessionHeader`, and resolves the
108
117
  * message list via Pi's own parser. A static snapshot — no subscription, no
109
118
  * streaming, no live tool registry. `readFile` is injected so this module makes
110
119
  * no `fs` calls.
@@ -140,6 +149,6 @@ export function liveSource(record: NavigableSubagent): TranscriptSource {
140
149
  function buildLabel(fields: LabelFields, registry: AgentConfigLookup, evicted = false): string {
141
150
  const name = getDisplayName(fields.type, registry);
142
151
  const duration = formatDuration(fields.startedAt, fields.completedAt);
143
- const marker = evicted ? " · evicted (snapshot)" : "";
144
- return `${name} (${fields.description}) · ${fields.toolUses} tools · ${fields.status} · ${duration}${marker}`;
152
+ const marker = evicted ? " · released (snapshot)" : "";
153
+ return `${name} (${fields.description}) · ${fields.modelLabel} · ${fields.toolUses} tools · ${fields.status} · ${duration}${marker}`;
145
154
  }
@@ -38,10 +38,9 @@ import {
38
38
  visibleWidth,
39
39
  } from "@earendil-works/pi-tui";
40
40
  import type { AgentConfigLookup } from "#src/config/agent-types";
41
- import type { EvictedSubagent } from "#src/lifecycle/subagent-manager";
42
41
  import type { SessionMessage } from "#src/types";
43
- import { describeActivity, type Theme } from "#src/ui/display";
44
- import { fileSnapshotSource, listNavigableAgents, liveSource, type NavigableSubagent, type TranscriptSource } from "#src/ui/session-navigation";
42
+ import { describeActivity, formatDuration, type Theme } from "#src/ui/display";
43
+ import { fileSnapshotSource, listNavigableAgents, liveSource, type NavigableSubagent, type RunDisplayMetadata, type TranscriptSource } from "#src/ui/session-navigation";
45
44
 
46
45
  // ─────────────────────────────────────────────────────────────────────────────
47
46
 
@@ -69,8 +68,6 @@ export interface SessionNavigatorUI {
69
68
  export interface SessionNavigatorParams {
70
69
  ui: SessionNavigatorUI;
71
70
  agents: readonly NavigableSubagent[];
72
- /** Descriptors of agents evicted by the cleanup sweep, sourced from disk when picked. */
73
- evicted: readonly EvictedSubagent[];
74
71
  registry: AgentConfigLookup;
75
72
  /** Working directory for tool-call rendering (relative path display). */
76
73
  cwd: string;
@@ -83,6 +80,7 @@ export interface TranscriptOverlayOptions {
83
80
  tui: TUI;
84
81
  theme: Theme;
85
82
  source: TranscriptSource;
83
+ run: RunDisplayMetadata;
86
84
  done: (result: undefined) => void;
87
85
  cwd: string;
88
86
  markdownTheme: MarkdownTheme;
@@ -96,8 +94,8 @@ export interface TranscriptOverlayOptions {
96
94
  * manager, so it stays a reactive consumer with no inbound call into the core.
97
95
  */
98
96
  export class SessionNavigatorHandler {
99
- async handle({ ui, agents, evicted, registry, cwd, readFile }: SessionNavigatorParams): Promise<void> {
100
- const entries = listNavigableAgents(agents, evicted, registry);
97
+ async handle({ ui, agents, registry, cwd, readFile }: SessionNavigatorParams): Promise<void> {
98
+ const entries = listNavigableAgents(agents, registry);
101
99
  if (entries.length === 0) {
102
100
  ui.notify("No subagent sessions to view.", "info");
103
101
  return;
@@ -120,7 +118,7 @@ export class SessionNavigatorHandler {
120
118
  const markdownTheme = getMarkdownTheme();
121
119
  await ui.custom<undefined>(
122
120
  (tui, theme, _keybindings, done) =>
123
- new TranscriptOverlay({ tui, theme, source, done, cwd, markdownTheme }),
121
+ new TranscriptOverlay({ tui, theme, source, run: entry.run, done, cwd, markdownTheme }),
124
122
  {
125
123
  overlay: true,
126
124
  overlayOptions: { anchor: "center", width: "90%", maxHeight: `${VIEWPORT_HEIGHT_PCT}%` },
@@ -142,20 +140,23 @@ export class TranscriptOverlay implements Component {
142
140
  private scrollOffset = 0;
143
141
  private autoScroll = true;
144
142
  private unsubscribe: (() => void) | undefined;
143
+ private runtimeInterval: ReturnType<typeof setInterval> | undefined;
145
144
  private closed = false;
146
145
 
147
146
  private readonly tui: TUI;
148
147
  private readonly theme: Theme;
149
148
  private readonly source: TranscriptSource;
149
+ private readonly run: RunDisplayMetadata;
150
150
  private readonly done: (result: undefined) => void;
151
151
  private readonly cwd: string;
152
152
  private readonly markdownTheme: MarkdownTheme;
153
153
  private content: Container;
154
154
 
155
- constructor({ tui, theme, source, done, cwd, markdownTheme }: TranscriptOverlayOptions) {
155
+ constructor({ tui, theme, source, run, done, cwd, markdownTheme }: TranscriptOverlayOptions) {
156
156
  this.tui = tui;
157
157
  this.theme = theme;
158
158
  this.source = source;
159
+ this.run = run;
159
160
  this.done = done;
160
161
  this.cwd = cwd;
161
162
  this.markdownTheme = markdownTheme;
@@ -165,11 +166,21 @@ export class TranscriptOverlay implements Component {
165
166
  this.content = this.rebuild();
166
167
  this.tui.requestRender();
167
168
  });
169
+ if (run.completedAt() === undefined) {
170
+ this.runtimeInterval = setInterval(() => {
171
+ if (this.closed || this.run.completedAt() !== undefined) {
172
+ this.clearRuntimeInterval();
173
+ return;
174
+ }
175
+ this.tui.requestRender();
176
+ }, 100);
177
+ }
168
178
  }
169
179
 
170
180
  handleInput(data: string): void {
171
181
  if (matchesKey(data, "escape") || matchesKey(data, "q")) {
172
182
  this.closed = true;
183
+ this.clearRuntimeInterval();
173
184
  this.done(undefined);
174
185
  return;
175
186
  }
@@ -213,7 +224,8 @@ export class TranscriptOverlay implements Component {
213
224
  const hrMid = row(th.fg("dim", "─".repeat(innerW)));
214
225
 
215
226
  lines.push(hrTop);
216
- lines.push(row(th.bold("Subagent session")));
227
+ const runtime = formatDuration(this.run.startedAt, this.run.completedAt());
228
+ lines.push(row(th.bold(`Subagent session · ${this.run.modelLabel} · ${runtime}`)));
217
229
  lines.push(hrMid);
218
230
 
219
231
  const contentLines = this.buildContentLines(innerW);
@@ -249,10 +261,18 @@ export class TranscriptOverlay implements Component {
249
261
  this.unsubscribe();
250
262
  this.unsubscribe = undefined;
251
263
  }
264
+ this.clearRuntimeInterval();
252
265
  }
253
266
 
254
267
  // ---- Private ----
255
268
 
269
+ private clearRuntimeInterval(): void {
270
+ if (this.runtimeInterval) {
271
+ clearInterval(this.runtimeInterval);
272
+ this.runtimeInterval = undefined;
273
+ }
274
+ }
275
+
256
276
  private innerWidth(): number {
257
277
  return Math.max(0, this.tui.terminal.columns - 4);
258
278
  }
@@ -5,9 +5,17 @@ export interface SubagentsSettingsManager {
5
5
  readonly maxConcurrent: number;
6
6
  readonly defaultMaxTurns: number | undefined;
7
7
  readonly graceTurns: number;
8
+ readonly consumedSessionRetentionMinutes: number;
9
+ readonly unconsumedSessionRetentionMinutes: number;
10
+ readonly abortAllOnInterrupt: boolean;
11
+ readonly fallbackSubagent: string | false | undefined;
8
12
  applyMaxConcurrent(n: number): { message: string; level: "info" | "warning" };
9
13
  applyDefaultMaxTurns(n: number): { message: string; level: "info" | "warning" };
10
14
  applyGraceTurns(n: number): { message: string; level: "info" | "warning" };
15
+ applyConsumedSessionRetention(n: number): { message: string; level: "info" | "warning" };
16
+ applyUnconsumedSessionRetention(n: number): { message: string; level: "info" | "warning" };
17
+ applyAbortAllOnInterrupt(value: boolean): { message: string; level: "info" | "warning" };
18
+ applyFallbackSubagent(value: string | false | undefined): { message: string; level: "info" | "warning" };
11
19
  }
12
20
 
13
21
  /** Narrow UI interface — only the ctx.ui methods the settings handler calls. */
@@ -17,6 +25,12 @@ export interface SubagentsSettingsUI {
17
25
  notify(message: string, level: "info" | "warning" | "error"): void;
18
26
  }
19
27
 
28
+ /** Registry operations needed to offer only valid fallback agents. */
29
+ export interface SubagentsSettingsAgentRegistry {
30
+ reload(): void;
31
+ getAvailableTypes(): string[];
32
+ }
33
+
20
34
  // ---- Class ----
21
35
 
22
36
  /**
@@ -26,13 +40,20 @@ export interface SubagentsSettingsUI {
26
40
  * settings list. Lifted from `AgentsMenuHandler.showSettings`.
27
41
  */
28
42
  export class SubagentsSettingsHandler {
29
- constructor(private readonly settings: SubagentsSettingsManager) {}
43
+ constructor(
44
+ private readonly settings: SubagentsSettingsManager,
45
+ private readonly agentRegistry: SubagentsSettingsAgentRegistry,
46
+ ) {}
30
47
 
31
48
  async handle({ ui }: { ui: SubagentsSettingsUI }): Promise<void> {
32
49
  const choice = await ui.select("Settings", [
33
50
  `Max concurrency (current: ${this.settings.maxConcurrent})`,
34
51
  `Default max turns (current: ${this.settings.defaultMaxTurns ?? "unlimited"})`,
35
52
  `Grace turns (current: ${this.settings.graceTurns})`,
53
+ `Consumed session retention (current: ${this.settings.consumedSessionRetentionMinutes}m)`,
54
+ `Unconsumed session retention (current: ${this.settings.unconsumedSessionRetentionMinutes}m)`,
55
+ `Abort all on ESC (current: ${this.settings.abortAllOnInterrupt ? "yes" : "no"})`,
56
+ `Unknown agent fallback (current: ${this.settings.fallbackSubagent === false ? "none" : this.settings.fallbackSubagent ?? "general-purpose"})`,
36
57
  ]);
37
58
  if (!choice) return;
38
59
 
@@ -65,19 +86,43 @@ export class SubagentsSettingsHandler {
65
86
  }
66
87
  }
67
88
  } else if (choice.startsWith("Grace turns")) {
68
- const val = await ui.input(
69
- "Grace turns after wrap-up steer",
70
- String(this.settings.graceTurns),
71
- );
72
- if (val) {
73
- const n = parseInt(val, 10);
74
- if (n >= 1) {
75
- const toast = this.settings.applyGraceTurns(n);
76
- ui.notify(toast.message, toast.level);
77
- } else {
78
- ui.notify("Must be a positive integer.", "warning");
79
- }
89
+ await this.applyNonNegativeInput(ui, "Grace turns after wrap-up steer", this.settings.graceTurns, 1, (n) => this.settings.applyGraceTurns(n));
90
+ } else if (choice.startsWith("Consumed session retention")) {
91
+ await this.applyNonNegativeInput(ui, "Minutes to retain a consumed live session", this.settings.consumedSessionRetentionMinutes, 0, (n) => this.settings.applyConsumedSessionRetention(n));
92
+ } else if (choice.startsWith("Unconsumed session retention")) {
93
+ await this.applyNonNegativeInput(ui, "Minutes to retain an unconsumed live session", this.settings.unconsumedSessionRetentionMinutes, 0, (n) => this.settings.applyUnconsumedSessionRetention(n));
94
+ } else if (choice.startsWith("Abort all on ESC")) {
95
+ const toast = this.settings.applyAbortAllOnInterrupt(!this.settings.abortAllOnInterrupt);
96
+ ui.notify(toast.message, toast.level);
97
+ } else if (choice.startsWith("Unknown agent fallback")) {
98
+ this.agentRegistry.reload();
99
+ const failClosed = "Fail closed (no fallback)";
100
+ const selected = await ui.select("Fallback for unknown agent types", [
101
+ failClosed,
102
+ ...this.agentRegistry.getAvailableTypes(),
103
+ ]);
104
+ if (selected) {
105
+ const toast = this.settings.applyFallbackSubagent(selected === failClosed ? false : selected);
106
+ ui.notify(toast.message, toast.level);
80
107
  }
81
108
  }
82
109
  }
110
+
111
+ private async applyNonNegativeInput(
112
+ ui: SubagentsSettingsUI,
113
+ title: string,
114
+ current: number,
115
+ minimum: number,
116
+ apply: (value: number) => { message: string; level: "info" | "warning" },
117
+ ): Promise<void> {
118
+ const val = await ui.input(title, String(current));
119
+ if (!val) return;
120
+ const n = Number(val);
121
+ if (!Number.isInteger(n) || n < minimum) {
122
+ ui.notify(minimum === 0 ? "Must be a non-negative integer." : "Must be a positive integer.", "warning");
123
+ return;
124
+ }
125
+ const toast = apply(n);
126
+ ui.notify(toast.message, toast.level);
127
+ }
83
128
  }
@@ -29,6 +29,7 @@ export interface WidgetAgent {
29
29
  readonly type: SubagentType;
30
30
  readonly status: string;
31
31
  readonly description: string;
32
+ readonly modelLabel: string;
32
33
  readonly toolUses: number;
33
34
  readonly startedAt: number;
34
35
  readonly completedAt?: number;
@@ -77,7 +78,7 @@ export function renderFinishedLine(
77
78
  statusText = theme.fg("warning", " aborted");
78
79
  }
79
80
 
80
- const parts: string[] = [];
81
+ const parts: string[] = [agent.modelLabel];
81
82
  parts.push(formatTurns(agent.turnCount, agent.maxTurns));
82
83
  if (agent.toolUses > 0) parts.push(`${agent.toolUses} tool use${agent.toolUses === 1 ? "" : "s"}`);
83
84
  parts.push(duration);
@@ -101,7 +102,7 @@ export function renderRunningLines(
101
102
  const tokens = getLifetimeTotal(agent.lifetimeUsage);
102
103
  const tokenText = tokens > 0 ? formatSessionTokens(tokens, agent.contextPercent, theme, agent.compactionCount) : "";
103
104
 
104
- const parts: string[] = [];
105
+ const parts: string[] = [agent.modelLabel];
105
106
  parts.push(formatTurns(agent.turnCount, agent.maxTurns));
106
107
  if (agent.toolUses > 0) parts.push(`${agent.toolUses} tool use${agent.toolUses === 1 ? "" : "s"}`);
107
108
  if (tokenText) parts.push(tokenText);
@@ -146,7 +147,7 @@ function categorizeAgents(
146
147
  interface WidgetSections {
147
148
  finishedLines: string[];
148
149
  runningLines: [string, string][];
149
- queuedLine: string | undefined;
150
+ queuedLines: string[];
150
151
  }
151
152
 
152
153
  /** Render each agent bucket into pre-formatted lines with ├─ tree connectors. */
@@ -171,11 +172,17 @@ function buildSections(
171
172
  ]);
172
173
  }
173
174
 
174
- const queuedLine = categories.queued.length > 0
175
- ? truncate(theme.fg("dim", "\u251C\u2500") + ` ${theme.fg("muted", "\u25E6")} ${theme.fg("dim", `${categories.queued.length} queued`)}`)
176
- : undefined;
175
+ const queuedLines = categories.queued.map((agent) =>
176
+ truncate(
177
+ theme.fg("dim", "\u251C\u2500")
178
+ + ` ${theme.fg("muted", "\u25E6")} ${theme.fg("dim", getDisplayName(agent.type, registry))}`
179
+ + ` ${theme.fg("dim", "·")} ${theme.fg("dim", agent.modelLabel)}`
180
+ + ` ${theme.fg("dim", "·")} ${theme.fg("dim", agent.description)}`
181
+ + ` ${theme.fg("dim", "· queued")}`,
182
+ ),
183
+ );
177
184
 
178
- return { finishedLines, runningLines, queuedLine };
185
+ return { finishedLines, runningLines, queuedLines };
179
186
  }
180
187
 
181
188
  /**
@@ -183,16 +190,16 @@ function buildSections(
183
190
  * Fixes the last tree connector: ├─ → └─, and │ → space for the running-agent activity line.
184
191
  */
185
192
  function assembleWithinBudget(heading: string, sections: WidgetSections): string[] {
186
- const { finishedLines, runningLines, queuedLine } = sections;
193
+ const { finishedLines, runningLines, queuedLines } = sections;
187
194
  const lines: string[] = [heading, ...finishedLines];
188
195
  for (const pair of runningLines) lines.push(...pair);
189
- if (queuedLine) lines.push(queuedLine);
196
+ lines.push(...queuedLines);
190
197
 
191
198
  // Fix last connector: swap \u251C\u2500 \u2192 \u2514\u2500.
192
199
  if (lines.length > 1) {
193
200
  const last = lines.length - 1;
194
201
  lines[last] = lines[last].replace("\u251C\u2500", "\u2514\u2500");
195
- if (runningLines.length > 0 && !queuedLine) {
202
+ if (runningLines.length > 0 && queuedLines.length === 0) {
196
203
  if (last >= 2) {
197
204
  lines[last - 1] = lines[last - 1].replace("\u251C\u2500", "\u2514\u2500");
198
205
  lines[last] = lines[last].replace("\u2502 ", " ");
@@ -213,10 +220,11 @@ function assembleOverflow(
213
220
  truncate: (line: string) => string,
214
221
  theme: Theme,
215
222
  ): string[] {
216
- const { finishedLines, runningLines, queuedLine } = sections;
223
+ const { finishedLines, runningLines, queuedLines } = sections;
217
224
  const lines: string[] = [heading];
218
225
  let budget = maxBody - 1;
219
226
  let hiddenRunning = 0;
227
+ let hiddenQueued = 0;
220
228
  let hiddenFinished = 0;
221
229
 
222
230
  for (const pair of runningLines) {
@@ -228,9 +236,13 @@ function assembleOverflow(
228
236
  }
229
237
  }
230
238
 
231
- if (queuedLine && budget >= 1) {
232
- lines.push(queuedLine);
233
- budget--;
239
+ for (const queuedLine of queuedLines) {
240
+ if (budget >= 1) {
241
+ lines.push(queuedLine);
242
+ budget--;
243
+ } else {
244
+ hiddenQueued++;
245
+ }
234
246
  }
235
247
 
236
248
  for (const fl of finishedLines) {
@@ -244,9 +256,10 @@ function assembleOverflow(
244
256
 
245
257
  const overflowParts: string[] = [];
246
258
  if (hiddenRunning > 0) overflowParts.push(`${hiddenRunning} running`);
259
+ if (hiddenQueued > 0) overflowParts.push(`${hiddenQueued} queued`);
247
260
  if (hiddenFinished > 0) overflowParts.push(`${hiddenFinished} finished`);
248
261
  const overflowText = overflowParts.join(", ");
249
- lines.push(truncate(theme.fg("dim", "\u2514\u2500") + ` ${theme.fg("dim", `+${hiddenRunning + hiddenFinished} more (${overflowText})`)}`));
262
+ lines.push(truncate(theme.fg("dim", "\u2514\u2500") + ` ${theme.fg("dim", `+${hiddenRunning + hiddenQueued + hiddenFinished} more (${overflowText})`)}`));
250
263
  return lines;
251
264
  }
252
265
 
@@ -272,7 +285,7 @@ export function renderWidgetLines(params: {
272
285
  const headingColor = hasActive ? "accent" : "dim";
273
286
  const headingIcon = hasActive ? "\u25CF" : "\u25CB";
274
287
 
275
- const { finishedLines, runningLines, queuedLine } = buildSections(
288
+ const { finishedLines, runningLines, queuedLines } = buildSections(
276
289
  { running, queued, finished },
277
290
  registry,
278
291
  spinnerFrame,
@@ -282,11 +295,11 @@ export function renderWidgetLines(params: {
282
295
 
283
296
  // Assemble with overflow cap (heading takes 1 line).
284
297
  const maxBody = MAX_WIDGET_LINES - 1;
285
- const totalBody = finishedLines.length + runningLines.length * 2 + (queuedLine ? 1 : 0);
298
+ const totalBody = finishedLines.length + runningLines.length * 2 + queuedLines.length;
286
299
  const heading = truncate(theme.fg(headingColor, headingIcon) + " " + theme.fg(headingColor, "Agents"));
287
300
 
288
301
  if (totalBody <= maxBody) {
289
- return assembleWithinBudget(heading, { finishedLines, runningLines, queuedLine });
302
+ return assembleWithinBudget(heading, { finishedLines, runningLines, queuedLines });
290
303
  }
291
- return assembleOverflow(heading, { finishedLines, runningLines, queuedLine }, maxBody, truncate, theme);
304
+ return assembleOverflow(heading, { finishedLines, runningLines, queuedLines }, maxBody, truncate, theme);
292
305
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nklisch/pi-plugins",
3
- "version": "0.2.5",
3
+ "version": "0.3.4",
4
4
  "private": false,
5
5
  "description": "Native marketplace and plugin lifecycle management for Pi, with Claude Code and Codex compatibility.",
6
6
  "license": "MIT",
@@ -67,8 +67,8 @@
67
67
  "@nklisch/pi-subagents"
68
68
  ],
69
69
  "dependencies": {
70
- "@nklisch/pi-mcp-adapter": "2.11.0-nklisch.7",
71
- "@nklisch/pi-subagents": "18.0.4-nklisch.1",
70
+ "@nklisch/pi-mcp-adapter": "2.20.1-nklisch.0",
71
+ "@nklisch/pi-subagents": "18.1.0-nklisch.0",
72
72
  "jiti": "2.7.0",
73
73
  "semver": "7.8.1",
74
74
  "smol-toml": "^1.7.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nklisch/pi-enhanced",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Pi, enhanced — one install for nklisch's full harness: policy-gated command review, plugin marketplace, subagents, background tasks, research tools, search, model modes, and a curated UX set.",
5
5
  "author": {
6
6
  "name": "nklisch"
@@ -7,12 +7,15 @@
7
7
  * resource path actually land in the pack?"
8
8
  */
9
9
  import { execFileSync } from "node:child_process";
10
- import { readFileSync } from "node:fs";
10
+ import { existsSync, readFileSync } from "node:fs";
11
11
  import { dirname, join } from "node:path";
12
12
  import { fileURLToPath } from "node:url";
13
13
 
14
14
  const root = join(dirname(fileURLToPath(import.meta.url)), "..");
15
15
  const manifest = JSON.parse(readFileSync(join(root, "package.json"), "utf8"));
16
+ const clearanceManifest = JSON.parse(
17
+ readFileSync(join(root, "../pi-clearance/package.json"), "utf8"),
18
+ );
16
19
 
17
20
  // Pack through the repo's bundle-aware packer; npm pack alone drops
18
21
  // bundleDependencies inside workspaces.
@@ -45,6 +48,30 @@ for (const dep of manifest.bundledDependencies ?? []) {
45
48
  if (!hit) failures.push(`node_modules/${dep}/package.json (bundled dependency missing)`);
46
49
  }
47
50
 
51
+ const clearancePrefix = "node_modules/@nklisch/pi-clearance/";
52
+ const targetSuffix = new Map([
53
+ ["x86_64-unknown-linux-gnu", "linux-x64-gnu"],
54
+ ["aarch64-unknown-linux-gnu", "linux-arm64-gnu"],
55
+ ["x86_64-apple-darwin", "darwin-x64"],
56
+ ["aarch64-apple-darwin", "darwin-arm64"],
57
+ ["x86_64-pc-windows-msvc", "win32-x64-msvc"],
58
+ ["aarch64-pc-windows-msvc", "win32-arm64-msvc"],
59
+ ]);
60
+ const nativeArtifacts = clearanceManifest.napi.targets.map((target) => {
61
+ const suffix = targetSuffix.get(target);
62
+ if (suffix === undefined) throw new Error(`Unknown Pi Clearance native target: ${target}`);
63
+ return `${clearanceManifest.napi.binaryName}.${suffix}.node`;
64
+ });
65
+ for (const artifact of nativeArtifacts) {
66
+ const staged = existsSync(join(root, "../pi-clearance/native", artifact));
67
+ if (process.env.PI_NATIVE_RELEASE_ARTIFACTS === "1" && !staged) {
68
+ failures.push(`release artifact was not staged: ${artifact}`);
69
+ }
70
+ if (staged && !files.has(`${clearancePrefix}native/${artifact}`)) {
71
+ failures.push(`bundled pi-clearance is missing native/${artifact}`);
72
+ }
73
+ }
74
+
48
75
  if (failures.length > 0) {
49
76
  console.error(`Bundle verification failed:\n- ${failures.join("\n- ")}`);
50
77
  process.exit(1);