@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
@@ -1,17 +1,19 @@
1
1
  import { chmod, lstat, mkdir, statfs, } from "node:fs/promises";
2
- import { isAbsolute, join, relative, resolve, sep, parse } from "node:path";
2
+ import { isAbsolute, resolve } from "node:path";
3
3
  const PRIVATE_DIRECTORY_MODE = 0o700;
4
4
  const PRIVATE_DATABASE_MODE = 0o600;
5
5
  /**
6
- * Filesystem types whose locking semantics are known to be local enough for
7
- * the SQLite adapter. The allowlist is intentionally conservative: an
8
- * unknown mount is a capability failure, not permission to silently fall back
9
- * to process-local coordination.
6
+ * Platforms where `statfs.f_type` carries a Linux-style filesystem magic
7
+ * number that identifies local-enough locking semantics for the SQLite
8
+ * adapter. This is a Linux-only signal: libuv returns `0` on Windows
9
+ * (libuv does not expose an NTFS magic via `statfs`), and on FreeBSD
10
+ * `statfs.f_type` is the kernel-assigned `vfc_typenum` (a small enum like
11
+ * `0x0095` for UFS, `0x0023` for ZFS), not the disk magics people sometimes
12
+ * copy from Linux headers — so an integer allowlist keyed on Linux magics
13
+ * would always fail closed there. Darwin is the same story (vestigial
14
+ * `0x1a`); see `verifyLocalFilesystemCapability` for the platform dispatch.
10
15
  */
11
- const LOCAL_FILESYSTEM_TYPES_BY_PLATFORM = {
12
- // Only filesystems whose SQLite locking behavior is covered by this
13
- // adapter's capability boundary are accepted. Unknown platform/type pairs
14
- // fail closed rather than inheriting a Linux guess.
16
+ const LOCAL_FILESYSTEM_MAGIC_BY_PLATFORM = {
15
17
  linux: new Set([
16
18
  0x0000ef53, // ext2/3/4
17
19
  0x01021994, // tmpfs
@@ -24,9 +26,6 @@ const LOCAL_FILESYSTEM_TYPES_BY_PLATFORM = {
24
26
  0x2fc12fc1, // zfs
25
27
  0x858458f6, // ramfs
26
28
  ]),
27
- win32: new Set([0x5346544e]), // NTFS
28
- darwin: new Set([0x41504653, 0x48465300]), // APFS, HFS+
29
- freebsd: new Set([0x011954, 0x09011954]), // UFS, UFS2
30
29
  };
31
30
  function filesystemMode(mode) {
32
31
  return mode & 0o777;
@@ -34,47 +33,31 @@ function filesystemMode(mode) {
34
33
  function filesystemFailure(message) {
35
34
  return new Error(message);
36
35
  }
37
- async function ensureDirectory(path) {
38
- try {
39
- const stats = await lstat(path);
40
- if (stats.isSymbolicLink())
41
- throw filesystemFailure("lock root contains a symbolic link");
42
- if (!stats.isDirectory())
43
- throw filesystemFailure("lock root component is not a directory");
44
- }
45
- catch (error) {
46
- if (error.code !== "ENOENT")
47
- throw error;
48
- try {
49
- await mkdir(path, { mode: PRIVATE_DIRECTORY_MODE });
50
- }
51
- catch (mkdirError) {
52
- // Another process may create the same first-use component after our
53
- // ENOENT observation. Accept only that race, then revalidate the winner
54
- // without following a symlink below.
55
- if (mkdirError.code !== "EEXIST")
56
- throw mkdirError;
57
- }
58
- const stats = await lstat(path);
59
- if (stats.isSymbolicLink() || !stats.isDirectory()) {
60
- throw filesystemFailure("lock root component is not a private directory");
61
- }
62
- }
63
- }
64
- /** Create and validate a private root without following any path symlink. */
36
+ /**
37
+ * Create and validate the lock root, then enforce that the leaf itself is
38
+ * private. The 0o700 leaf mode is the actual security boundary: no other
39
+ * local user can write into a directory the runtime user owns at 0o700,
40
+ * regardless of how the path arrived there.
41
+ *
42
+ * Earlier versions walked every ancestor and rejected any path component
43
+ * symlink. That defense assumed an attacker with write access to a parent of
44
+ * the lock root — at which point the user is already compromised — while it
45
+ * broke legitimate OS-managed symlinks such as macOS `/tmp → /private/tmp`.
46
+ * The walk is gone; the leaf check is what carries the guarantee.
47
+ */
65
48
  export async function ensurePrivateLockRoot(input) {
66
49
  if (typeof input !== "string" || input.length === 0 || !isAbsolute(input)) {
67
50
  throw new TypeError("lockRoot must be a non-empty absolute path");
68
51
  }
69
52
  const root = resolve(input);
70
- const parsed = parse(root);
71
- const remainder = relative(parsed.root, root);
72
- let current = parsed.root;
73
- for (const component of remainder.split(sep)) {
74
- if (component.length === 0)
75
- continue;
76
- current = join(current, component);
77
- await ensureDirectory(current);
53
+ try {
54
+ await mkdir(root, { mode: PRIVATE_DIRECTORY_MODE, recursive: true });
55
+ }
56
+ catch (mkdirError) {
57
+ // A concurrent creator may win the race after our first attempt. Accept
58
+ // only that race; the leaf revalidation below catches anything else.
59
+ if (mkdirError.code !== "EEXIST")
60
+ throw mkdirError;
78
61
  }
79
62
  await chmod(root, PRIVATE_DIRECTORY_MODE);
80
63
  const stats = await lstat(root);
@@ -87,12 +70,25 @@ export async function ensurePrivateLockRoot(input) {
87
70
  * Verify the mounted filesystem rather than assuming that a successful SQLite
88
71
  * open proves cross-process exclusion. Callers may inject a stricter policy
89
72
  * when a platform has a better local-filesystem classifier.
73
+ *
74
+ * The integer magic-number allowlist applies only to Linux, where
75
+ * `statfs.f_type` carries a filesystem magic. On every other platform
76
+ * (Darwin, Windows, FreeBSD, AIX, etc.) the gate is a no-op: libuv returns
77
+ * `0` on Windows, FreeBSD's `f_type` is a kernel enum (`vfc_typenum`), and
78
+ * Darwin's is vestigial `0x1a` (issue #2). A fail-closed stance on those
79
+ * platforms has no signal and breaks real startup. SQLite locking works
80
+ * empirically on those platforms; the allowlist is a defense against
81
+ * known-broken network filesystems on Linux, not a pre-condition for the
82
+ * adapter to function. Callers needing a real classification on other
83
+ * platforms must inject `verifyLocalFilesystem`.
90
84
  */
91
85
  export async function verifyLocalFilesystemCapability(root) {
86
+ const supportedTypes = LOCAL_FILESYSTEM_MAGIC_BY_PLATFORM[process.platform];
87
+ if (supportedTypes === undefined)
88
+ return;
92
89
  const stats = await statfs(root);
93
90
  const type = Number(stats.type);
94
- const supportedTypes = LOCAL_FILESYSTEM_TYPES_BY_PLATFORM[process.platform];
95
- if (supportedTypes === undefined || !Number.isSafeInteger(type) || !supportedTypes.has(type >>> 0)) {
91
+ if (!Number.isSafeInteger(type) || !supportedTypes.has(type >>> 0)) {
96
92
  throw filesystemFailure("filesystem locking capability is unknown or unsupported on this platform");
97
93
  }
98
94
  }
@@ -1 +1 @@
1
- {"version":3,"file":"local-lock-filesystem.js","sourceRoot":"","sources":["../../../src/infrastructure/state/local-lock-filesystem.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"local-lock-filesystem.js","sourceRoot":"","sources":["../../../src/infrastructure/state/local-lock-filesystem.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EACL,KAAK,EACL,KAAK,EACL,MAAM,GACP,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEhD,MAAM,sBAAsB,GAAG,KAAK,CAAC;AACrC,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAEpC;;;;;;;;;;GAUG;AACH,MAAM,kCAAkC,GAAkD;IACxF,KAAK,EAAE,IAAI,GAAG,CAAC;QACb,UAAU,EAAE,WAAW;QACvB,UAAU,EAAE,QAAQ;QACpB,UAAU,EAAE,MAAM;QAClB,UAAU,EAAE,WAAW;QACvB,UAAU,EAAE,MAAM;QAClB,UAAU,EAAE,YAAY;QACxB,UAAU,EAAE,QAAQ;QACpB,UAAU,EAAE,OAAO;QACnB,UAAU,EAAE,MAAM;QAClB,UAAU,EAAE,QAAQ;KACrB,CAAC;CACH,CAAC;AAEF,SAAS,cAAc,CAAC,IAAY;IAClC,OAAO,IAAI,GAAG,KAAK,CAAC;AACtB,CAAC;AAED,SAAS,iBAAiB,CAAC,OAAe;IACxC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;AAC5B,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,KAAa;IACvD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1E,MAAM,IAAI,SAAS,CAAC,4CAA4C,CAAC,CAAC;IACpE,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IAC5B,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,sBAAsB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvE,CAAC;IAAC,OAAO,UAAU,EAAE,CAAC;QACpB,wEAAwE;QACxE,qEAAqE;QACrE,IAAK,UAAoC,CAAC,IAAI,KAAK,QAAQ;YAAE,MAAM,UAAU,CAAC;IAChF,CAAC;IACD,MAAM,KAAK,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,KAAK,CAAC,cAAc,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,sBAAsB,EAAE,CAAC;QAC5G,MAAM,iBAAiB,CAAC,0BAA0B,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,+BAA+B,CAAC,IAAY;IAChE,MAAM,cAAc,GAAG,kCAAkC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC5E,IAAI,cAAc,KAAK,SAAS;QAAE,OAAO;IACzC,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC;QACnE,MAAM,iBAAiB,CAAC,0EAA0E,CAAC,CAAC;IACtG,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,yBAAyB,GAAG,sBAAsB,CAAC;AAChE,MAAM,CAAC,MAAM,wBAAwB,GAAG,qBAAqB,CAAC"}
@@ -2,10 +2,10 @@ import { probePublishedPackage, } from "../published-package-receipt.js";
2
2
  import { createPiMcpRuntime, } from "./pi-mcp-adapter-runtime.js";
3
3
  export const PI_MCP_ADAPTER_RECEIPT = Object.freeze({
4
4
  packageName: "@nklisch/pi-mcp-adapter",
5
- version: "2.11.0-nklisch.7",
5
+ version: "2.20.1-nklisch.0",
6
6
  license: "MIT",
7
7
  nodeEngine: ">=22.19.0",
8
- piPeerRange: ">=0.79.1 <1",
8
+ piPeerRange: ">=0.82.0 <1",
9
9
  requiredExports: [".", "./programmatic"],
10
10
  piExtensions: ["./index.ts"],
11
11
  });
@@ -4,9 +4,9 @@ import { BoundaryError, DiagnosticSchema, ErrorCodeRegistry, diagnosticFromZodEr
4
4
  const PACKAGE_PROVIDER = Object.freeze({
5
5
  kind: "published-package",
6
6
  packageName: "@nklisch/pi-mcp-adapter",
7
- version: "2.11.0-nklisch.7",
7
+ version: "2.20.1-nklisch.0",
8
8
  nodeEngine: ">=22.19.0",
9
- piPeerRange: ">=0.79.1 <1",
9
+ piPeerRange: ">=0.82.0 <1",
10
10
  contractVersion: 1,
11
11
  });
12
12
  function safeIdentity(identity) {
@@ -7,7 +7,7 @@ const PACKAGE_INTEGRITY = "sha512-33Q8JDffXUuiT1M3XjLXCI4If9p+3AOwsUp/b5f1+B7Y5J
7
7
  const PACKAGE_RELEASE_TAG = "pi-subagents-v18.0.4-nklisch.1";
8
8
  const PACKAGE_COMMIT = "43efffb459f64e2f5f9aaee50d8ae5afa564f4f3";
9
9
  const PACKAGE_NODE_ENGINE = ">=22";
10
- const PACKAGE_PI_PEER_RANGE = ">=0.75.0";
10
+ const PACKAGE_PI_PEER_RANGE = ">=0.80.5";
11
11
  const PACKAGE_CONTINUATION_BUDGET = 3;
12
12
  // This digest covers the three unchanged portable conformance vectors: the
13
13
  // reusable trace contract, its negative controls, and its port integration.
@@ -6,10 +6,10 @@ import { createJiti } from "jiti/static";
6
6
  import { probePublishedPackage, } from "../published-package-receipt.js";
7
7
  export const PI_SUBAGENTS_RECEIPT = Object.freeze({
8
8
  packageName: "@nklisch/pi-subagents",
9
- version: "18.0.4-nklisch.1",
9
+ version: "18.1.0-nklisch.0",
10
10
  license: "MIT",
11
11
  nodeEngine: ">=22",
12
- piPeerRange: ">=0.75.0",
12
+ piPeerRange: ">=0.80.5",
13
13
  requiredExports: [".", "./settings"],
14
14
  piExtensions: ["./src/index.ts"],
15
15
  });
@@ -18,18 +18,17 @@ Run them in foreground or background, steer them mid-run, resume completed sessi
18
18
  - **In-process & native** — agents run inside the same pi runtime (no spawned subprocesses), sharing tool names, calling conventions, and UI patterns (`subagent`, `get_subagent_result`, `steer_subagent`) — feels native
19
19
  - **Parallel background agents** — spawn multiple agents that run concurrently with automatic queuing (configurable concurrency limit, default 4) and individual completion notifications
20
20
  - **Live widget UI** — persistent above-editor widget with animated spinners, live tool activity, token counts, and colored status icons
21
- - **Session transcripts** — open any subagent's full session transcript (running or evicted) in pi's native read-only viewer via `/subagents:sessions`
22
- - **Custom agent types** — define agents in `.pi/agents/<name>.md` with YAML frontmatter: custom system prompts, model selection, thinking levels, tool restrictions
21
+ - **Session transcripts** — open any subagent's full session transcript, including records whose heavy live session has been released, in pi's native read-only viewer via `/subagents:sessions`
22
+ - **Custom agent types** — define project agents in `.pi/agents/<name>.md` or the shared `.agents/agents/<name>.md` convention, with YAML frontmatter for prompts, models, thinking, and built-in tools
23
23
  - **Mid-run steering** — inject messages into running agents to redirect their work without restarting
24
24
  - **Session resume** — pick up where an agent left off, preserving full conversation context
25
25
  - **Graceful turn limits** — agents get a "wrap up" warning before hard abort, producing clean partial results instead of cut-off output
26
- - **Case-insensitive agent types** — `"explore"`, `"Explore"`, `"EXPLORE"` all work.
27
- Unknown types fall back to general-purpose with a note
26
+ - **Policy-aware agent types** — unambiguous names resolve case-insensitively. Unknown names default to `general-purpose`, can target another enabled fallback, or can fail closed via `fallbackSubagent`
28
27
  - **Fuzzy model selection** — specify models by name (`"haiku"`, `"sonnet"`) instead of full IDs, with automatic filtering to only available/configured models
29
28
  - **Context inheritance** — optionally fork the parent conversation into a sub-agent so it knows what's been discussed
30
29
  - **Styled completion notifications** — background agent results render as themed, compact notification boxes (icon, stats, result preview) instead of raw XML.
31
30
  Expandable to show full output
32
- - **Event bus** — lifecycle events (`subagents:created`, `started`, `completed`, `failed`, `steered`, `compacted`) emitted via `pi.events`, enabling other extensions to react to sub-agent activity
31
+ - **Event bus** — lifecycle events (`subagents:created`, `started`, `completed`, `failed`, `resumed`, `steered`, `compacted`) emitted via `pi.events`, enabling other extensions to react to sub-agent activity
33
32
 
34
33
  ## Install
35
34
 
@@ -108,12 +107,11 @@ The LLM receives structured `<task-notification>` XML for parsing, while the use
108
107
 
109
108
  | Type | Tools | Model | Prompt Mode | Description |
110
109
  | ----------------- | -------------------------- | ----------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------ |
111
- | `general-purpose` | all 7 | inherit | `append` (parent twin) | Inherits the parent's full system prompt — same rules, CLAUDE.md, project conventions |
112
- | `Explore` | read, bash, grep, find, ls | haiku (falls back to inherit) | `replace` | Fast codebase exploration (read-only); inherits the parent prompt as a base |
113
- | `Plan` | read, bash, grep, find, ls | inherit | `replace` | Software architect for implementation planning (read-only); inherits the parent prompt as a base |
110
+ | `general-purpose` | all 7 | inherit | `append` (parent twin) | Inherits the parent's full system prompt — same rules, CLAUDE.md, project conventions |
111
+ | `Explore` | read, bash, grep, find, ls | haiku (falls back to inherit) | `replace` | Fast codebase exploration (read-only); inherits the parent prompt as a base |
114
112
 
115
113
  The `general-purpose` agent is a **parent twin** — it receives the parent's entire system prompt plus a sub-agent context bridge, so it follows the same rules the parent does.
116
- Explore and Plan use `replace` mode: the parent prompt is the cacheable base and their specialist read-only instructions are appended last, giving them the final say.
114
+ Explore uses `replace` mode: the parent prompt is the cacheable base and its specialist read-only instructions are appended last, giving those instructions the final say.
117
115
 
118
116
  Default agents can be **overridden** by creating a `.md` file with the same name (e.g. `.pi/agents/general-purpose.md`), or **disabled** per-project with `enabled: false` frontmatter.
119
117
 
@@ -123,14 +121,15 @@ Define custom agent types by creating `.md` files.
123
121
  The filename becomes the agent type name.
124
122
  Any name is allowed — using a default agent's name overrides it.
125
123
 
126
- Agents are discovered from two locations (higher priority wins):
124
+ Agents are discovered from three locations (higher priority wins):
127
125
 
128
- | Priority | Location | Scope |
129
- | ----------- | -------------------------------------------------------------------------------- | ----------------------------- |
130
- | 1 (highest) | `.pi/agents/<name>.md` | Project per-repo agents |
131
- | 2 | `$PI_CODING_AGENT_DIR/agents/<name>.md` (default `~/.pi/agent/agents/<name>.md`) | Global available everywhere |
126
+ | Priority | Location | Scope |
127
+ | ----------- | -------------------------------------------------------------------------------- | -------------------------------------- |
128
+ | 1 (highest) | `.pi/agents/<name>.md` | Pi project authority |
129
+ | 2 | `.agents/agents/<name>.md` | Shared cross-tool project definitions |
130
+ | 3 | `$PI_CODING_AGENT_DIR/agents/<name>.md` (default `~/.pi/agent/agents/<name>.md`) | Global — available everywhere |
132
131
 
133
- Project-level agents override global ones with the same name, so you can customize a global agent for a specific project.
132
+ `.agents/agents` is read-only to this extension. `.pi/agents` overrides it and the global location on name collisions.
134
133
  The global location follows the upstream `PI_CODING_AGENT_DIR` env var — set it to relocate all pi-coding-agent state (agents, skills, settings) to a custom directory.
135
134
 
136
135
  ### Example: `.pi/agents/auditor.md`
@@ -169,9 +168,9 @@ All fields are optional — sensible defaults for everything.
169
168
  | ------------------- | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
170
169
  | `description` | filename | Agent description shown in tool listings |
171
170
  | `display_name` | — | Display name for UI (e.g. widget, agent list) |
172
- | `tools` | all 7 | Comma-separated built-in tools: read, bash, edit, write, grep, find, ls. `none` for no tools |
171
+ | `tools` | all 7 | Comma-separated built-in tools: read, bash, edit, write, grep, find, ls. `none` denies all built-ins. Parent extension tools remain inheritable and are narrowed by extension policy |
173
172
  | `model` | inherit parent | Model — `provider/modelId` or fuzzy name (`"haiku"`, `"sonnet"`) |
174
- | `thinking` | inherit | off, minimal, low, medium, high, xhigh |
173
+ | `thinking` | inherit | off, minimal, low, medium, high, xhigh, max (actual support depends on host and model) |
175
174
  | `max_turns` | unlimited | Max agentic turns before graceful shutdown. `0` or omit for unlimited |
176
175
  | `prompt_mode` | `append` | `replace`: parent prompt is the cacheable base; body is appended last with full control (no `<sub_agent_context>` bridge, no `<agent_instructions>` wrapper). `append`: parent prompt is the base; body is wrapped in `<agent_instructions>` and a sub-agent context bridge is injected (agent acts as a "parent twin") |
177
176
  | `inherit_context` | `false` | Fork parent conversation into agent |
@@ -194,15 +193,23 @@ Launch a sub-agent.
194
193
  | `description` | string | yes | Short 3-5 word summary (shown in UI) |
195
194
  | `subagent_type` | string | yes | Agent type (built-in or custom) |
196
195
  | `model` | string | no | Model — `provider/modelId` or fuzzy name (`"haiku"`, `"sonnet"`) |
197
- | `thinking` | string | no | Thinking level: off, minimal, low, medium, high, xhigh |
196
+ | `thinking` | string | no | Thinking level: off, minimal, low, medium, high, xhigh, max |
198
197
  | `max_turns` | number | no | Max agentic turns. Omit for unlimited (default) |
199
198
  | `run_in_background` | boolean | no | Run without blocking |
200
- | `resume` | string | no | Agent ID to resume a previous session |
199
+ | `resume` | string | no | Retained, finished agent ID to continue with the same history |
201
200
  | `inherit_context` | boolean | no | Fork parent conversation into agent |
202
201
 
202
+ ### Choosing the next action
203
+
204
+ - Let background agents finish normally. Completion automatically wakes the parent with a result preview; do not poll.
205
+ - Use `steer_subagent` to redirect an agent that is still running.
206
+ - Use `resume` after an agent finishes when it should continue with the same retained conversation history.
207
+ - Launch a new subagent without `resume` when prior conversation history is unnecessary.
208
+ - Use `get_subagent_result` only for full output, verbose conversation, an explicit status check or synchronization point, or recovery after a missed notification.
209
+
203
210
  ### `get_subagent_result`
204
211
 
205
- Check status and retrieve results from a background agent.
212
+ Inspect status or retrieve full results from a background agent. It is not the normal completion path because completion notifications wake the parent automatically.
206
213
 
207
214
  | Parameter | Type | Required | Description |
208
215
  | ---------- | ------- | -------- | ----------------------------- |
@@ -224,17 +231,17 @@ The message interrupts after the current tool execution.
224
231
 
225
232
  | Command | Description |
226
233
  | --------------------- | ------------------------------------------------------ |
227
- | `/subagents:settings` | Configure subagent settings (concurrency, turn limits) |
234
+ | `/subagents:settings` | Configure concurrency, turn limits, retention, interrupt behavior, and unknown-type fallback |
228
235
  | `/subagents:sessions` | View a subagent's session transcript (read-only) |
229
236
 
230
237
  ### `/subagents:settings`
231
238
 
232
- Interactive list to tune runtime settings — max concurrency, default max turns, and grace turns.
239
+ Interactive list to tune max concurrency, default/grace turns, consumed and unconsumed live-session retention, abort-all-on-ESC behavior, and unknown-agent fallback.
233
240
  Changes persist across pi restarts (see [Persistent Settings](#persistent-settings)).
234
241
 
235
242
  ### `/subagents:sessions`
236
243
 
237
- Pick any subagent — running or already evicted — and read its full session transcript in pi's native per-entry viewer.
244
+ Pick any subagent — running, completed, or retained after its live session was released — and read its full session transcript in pi's native per-entry viewer.
238
245
  Read-only: no steering, no session takeover (steering lives in the `steer_subagent` tool and the background widget).
239
246
 
240
247
  Creating and editing agent definitions is not a command — write an agent `.md` file in your editor, or ask a pi session to generate one (see [Custom Agents](#custom-agents)).
@@ -257,14 +264,13 @@ Instead of hard-aborting at the turn limit, agents get a graceful shutdown:
257
264
  ## Concurrency
258
265
 
259
266
  Background agents are subject to a configurable concurrency limit (default: 4).
260
- Excess agents are automatically queued and start as running agents complete.
261
- The widget shows queued agents as a collapsed count.
267
+ Excess agents are automatically queued and start as running agents complete. The widget shows each queued agent with its effective model and queued state. Stopping a queued agent follows the normal terminal lifecycle and reports that no work started.
262
268
 
263
- Foreground agents bypass the queue — they block the parent anyway.
269
+ Foreground agents bypass the queue — they block the parent anyway. Completion nudges are held while the parent is running and flushed at the parent run boundary, preventing a pulled result from also arriving as a duplicate notification.
264
270
 
265
271
  ## Persistent Settings
266
272
 
267
- Runtime tuning values set via `/subagents:settings` (max concurrency, default max turns, grace turns) persist across pi restarts.
273
+ Runtime tuning values set via `/subagents:settings` persist across pi restarts. Terminal records remain available for the whole parent session. Their heavy live sessions are released after the consumed or unconsumed retention window; the result and persisted transcript pointer remain available.
268
274
  Two files, merged on load:
269
275
 
270
276
  - **Global:** `~/.pi/agent/subagents.json` — your machine-wide defaults.
@@ -273,7 +279,7 @@ Two files, merged on load:
273
279
  Written by `/subagents:settings`.
274
280
 
275
281
  **Precedence:** project overrides global on any field present in both.
276
- Missing fields fall back to the hardcoded defaults (max concurrency `4`, default max turns unlimited, grace turns `5`).
282
+ Missing fields use these defaults: max concurrency `4`, max turns unlimited, grace turns `5`, consumed-session retention `10` minutes, unconsumed-session retention `720` minutes, abort all on parent ESC enabled, and unknown-agent fallback `general-purpose`.
277
283
 
278
284
  **Example — global defaults for a beefy machine:**
279
285
 
@@ -282,12 +288,15 @@ mkdir -p ~/.pi/agent
282
288
  cat > ~/.pi/agent/subagents.json <<'EOF'
283
289
  {
284
290
  "maxConcurrent": 16,
285
- "graceTurns": 10
291
+ "graceTurns": 10,
292
+ "unconsumedSessionRetentionMinutes": 1440,
293
+ "abortAllOnInterrupt": false,
294
+ "fallbackSubagent": false
286
295
  }
287
296
  EOF
288
297
  ```
289
298
 
290
- Every project now starts with concurrency 16 and grace 10, without ever touching the command.
299
+ Every project now starts with concurrency 16, grace 10, a one-day unconsumed retention cap, background agents surviving parent ESC, and unknown agent types failing closed.
291
300
  Individual projects can still override via `/subagents:settings`.
292
301
 
293
302
  **Failure behavior:** missing file is silent; malformed JSON logs a `[pi-subagents] Ignoring malformed settings at …` warning to stderr; invalid/out-of-range field values are dropped per-field; write failures downgrade the `/subagents:settings` toast to a warning with `(session only; failed to persist)`.
@@ -301,6 +310,7 @@ Agent lifecycle events are emitted via `pi.events.emit()` so other extensions ca
301
310
  | `subagents:created` | Background agent registered | `id`, `type`, `description`, `isBackground` |
302
311
  | `subagents:started` | Agent transitions to running (including queued→running) | `id`, `type`, `description` |
303
312
  | `subagents:completed` | Agent finished successfully | `id`, `type`, `durationMs`, `tokens` (lifetime `{ input, output, total }`), `toolUses`, `result` |
313
+ | `subagents:resumed` | A resumed turn reached a terminal state | completed-event shape plus `status` and `error` |
304
314
  | `subagents:failed` | Agent errored, stopped, or aborted | same as completed + `error`, `status` |
305
315
  | `subagents:steered` | Steering message sent | `id`, `message` |
306
316
  | `subagents:compacted` | Agent's session successfully compacted | `id`, `type`, `description`, `reason` (`"manual"` / `"threshold"` / `"overflow"`), `tokensBefore`, `compactionCount` |
@@ -320,7 +330,7 @@ The earlier `isolation: "worktree"` spawn flag and `isolation:` frontmatter key
320
330
  ## Removed: agent memory and skill preloading
321
331
 
322
332
  Persistent agent memory (the `memory:` frontmatter key) and skill preloading (the `skills:` frontmatter key) were removed when the core was slimmed down.
323
- Children now always inherit the parent's skills and extensions, so the `isolated`, `extensions`, and `skills` frontmatter keys no longer exist.
333
+ Children always inherit the parent's skills and extensions, so the `isolated`, `extensions`, and `skills` frontmatter keys no longer exist. Child creation uses a denylist rather than a registration-time allowlist: extension tools—including tools registered during lifecycle hooks—remain available, while disallowed built-ins and the three recursive orchestration tools stay excluded.
324
334
 
325
335
  ## Migrating from `disallowed_tools`
326
336
 
@@ -87,7 +87,7 @@ interface SubagentLifecycleRegistration {
87
87
  /** Agent type: any string name (built-in defaults or user-defined). */
88
88
  type SubagentType = string;
89
89
  interface AgentInvocation {
90
- /** Short display name, e.g. "haiku" only set when different from parent. */
90
+ /** Exact effective model label in `provider/id` form. */
91
91
  modelName?: string;
92
92
  thinking?: ThinkingLevel;
93
93
  maxTurns?: number;
@@ -239,6 +239,7 @@ interface SubagentsService {
239
239
  declare const SUBAGENT_EVENTS: {
240
240
  readonly STARTED: "subagents:started";
241
241
  readonly COMPLETED: "subagents:completed";
242
+ readonly RESUMED: "subagents:resumed";
242
243
  readonly FAILED: "subagents:failed";
243
244
  readonly COMPACTED: "subagents:compacted";
244
245
  readonly CREATED: "subagents:created";
@@ -1,22 +1,24 @@
1
1
  # Maintained-fork policy
2
2
 
3
3
  `@nklisch/pi-subagents` is a published MIT fork of `@gotgenes/pi-subagents`,
4
- most recently cut as `18.0.4-nklisch.0` on the upstream 18.0.4 release
5
- (upstream base commit `c76a294a777a990950da23fc06cb0caf51da7ac6` line).
4
+ initially cut as `18.0.4-nklisch.0` from upstream base commit
5
+ `c76a294a777a990950da23fc06cb0caf51da7ac6`, whose package version is 18.0.3.
6
+ The fork version did not correspond to an upstream 18.0.4 release.
6
7
  Since 2026-07 its home is the `nklisch/pi-extensions` monorepo
7
8
  (`packages/pi-subagents`); earlier history lives in the `nklisch/pi-packages`
8
9
  fork.
9
10
 
10
- The fork retains upstream history, copyright notices, license, exports, Pi
11
- extension behavior, peer ranges, and package layout. Its intentional delta is
12
- the documented ordered lifecycle-interceptor provider seam (ADR 0005) and its
13
- tests.
11
+ The fork retains upstream history, copyright notices, license, exports, and
12
+ package layout. Its intentional delta includes the documented ordered
13
+ lifecycle-interceptor provider seam (ADR 0005), exact model/runtime visibility,
14
+ and selected post-base reliability adaptations. It requires Pi coding-agent
15
+ `>=0.80.5` so completion nudges can synchronize on `agent_settled`.
14
16
 
15
17
  ## Release policy
16
18
 
17
19
  Each fork release must:
18
20
 
19
- 1. rebase the narrow generic commits onto a current verified upstream release;
21
+ 1. selectively rebase or port current verified upstream changes, preserving the fork's lifecycle-interceptor and exact model/runtime contracts;
20
22
  2. choose a `-nklisch.N` suffix on the upstream version it tracks;
21
23
  3. capture registry integrity and tag/commit provenance;
22
24
  4. run the package and consumer qualification suites (pi-plugins' bundled
@@ -32,7 +34,11 @@ only, not lifecycle semantics or consumer contracts.
32
34
 
33
35
  ## Scope guard
34
36
 
35
- The published package excludes the experimental UI layer that existed
36
- mid-refactor on the import branch (agent editors, wizards, conversation
37
- viewers). Reviving any UI direction is a new decision, not a restoration —
38
- see ADR 0004 for the history.
37
+ The published package keeps the narrow built-in background widget, session
38
+ navigator, and settings command accepted by ADR 0004. These status surfaces
39
+ show each subagent's exact effective model and elapsed or final runtime. The
40
+ package excludes the retired agent editors, wizards, and bespoke conversation
41
+ viewer from the import branch. Reviving those surfaces is a new decision, not
42
+ a restoration. Children inherit extension tools through a registration-open
43
+ denylist policy; scheduling, memory, nested delegation, worktrees, and RPC stay
44
+ outside the core.
@@ -8,8 +8,9 @@ order — capability the observational lifecycle events cannot provide.
8
8
 
9
9
  ## Product shape
10
10
 
11
- - A minimal core that owns configuration, models, sessions, tools, queueing,
12
- concurrency, persistence, workspaces, turn limits, and disposal.
11
+ - A minimal core that owns configuration, model-runtime inheritance, sessions,
12
+ tools, queueing, concurrency, consumption-aware retention, workspaces, turn
13
+ limits, and disposal.
13
14
  - Extensions — including the fork's own interceptor seam — compose on that
14
15
  core rather than forking it (ADR 0002).
15
16
  - Two public entrypoints only: the root service contract and `./settings`.
@@ -19,14 +20,20 @@ order — capability the observational lifecycle events cannot provide.
19
20
  ## Consumers and compatibility
20
21
 
21
22
  The root export is loaded by pi-plugins through a verified packaged loader;
22
- its shape is a hard compatibility surface. The published package
23
- deliberately excludes the experimental UI layer that existed mid-refactor
24
- on the import branch (see ADR 0004 for the UI direction history).
23
+ its shape is a hard compatibility surface. The published package includes a narrow built-in operator UI: the background
24
+ status widget, session navigator, and settings command. Every subagent status
25
+ surface identifies the exact effective model and elapsed or final runtime. The
26
+ package excludes the retired experimental editors, wizards, and bespoke
27
+ conversation viewer from the import branch (see ADR 0004 for the UI direction
28
+ history). Child sessions inherit parent extension tools through a denylist
29
+ policy so synchronous and lifecycle-time registrations remain available without
30
+ exposing recursive orchestration tools.
25
31
 
26
32
  ## Fork posture
27
33
 
28
- Track `gotgenes/pi-packages` for upstream releases and security reports;
29
- rebase the narrow fork delta onto verified upstream releases; contribute
34
+ Track `gotgenes/pi-packages` and the original `tintinweb/pi-subagents` lineage
35
+ for releases and security reports; selectively port verified changes without
36
+ surrendering the fork's stronger contracts; contribute
30
37
  the generic seam upstream when its contract is proven. Returning to
31
38
  upstream must change package selection only, never lifecycle semantics or
32
39
  consumer contracts. See `FORK-MAINTENANCE.md`.
@@ -15,8 +15,7 @@ This document describes the architecture of the pi-subagents fork: a focused, co
15
15
  The max-concurrent admission gate is not scheduling in this sense — concurrency management stays in core.
16
16
  5. **UI is an in-core, substitutable consumer** — [ADR-0004](../decisions/0004-reconsider-ui-direction.md) records the per-component decision: the widget shrinks to background agents only, the bespoke conversation viewer is replaced by native session navigation, the `/agents` command is dissolved into focused surfaces, and the surviving UI stays in the core as a reactive consumer (not extracted to a separate package).
17
17
  Extraction remains an available future option because the composition invariant holds — the core is byte-for-byte identical with or without a given UI consumer.
18
- 6. **Snapshot, don't capture** — mutable parent state (ctx, session, model) is read once at spawn time and frozen into a `ParentSnapshot` data object.
19
- No live references survive past the spawn call.
18
+ 6. **Snapshot identity; share the canonical runtime** — mutable parent identity and prompt state are frozen into `ParentSnapshot` at spawn. The parent `ModelRuntime` is deliberately shared so child sessions preserve runtime provider and authentication registrations; no live session context is captured.
20
19
  7. **Subscribe, don't thread** — observation of agent progress uses direct session-event subscription, not callback parameters threaded through multiple layers.
21
20
  8. **Construct complete** — objects are born with all their dependencies.
22
21
  If state isn't available yet, the object that needs it doesn't exist yet.
@@ -180,6 +179,7 @@ classDiagram
180
179
  +systemPrompt: string
181
180
  +model: unknown
182
181
  +modelRegistry: unknown
182
+ +modelRuntime?: unknown
183
183
  +parentContext?: string
184
184
  }
185
185
 
@@ -208,6 +208,7 @@ stateDiagram-v2
208
208
  [*] --> queued : spawn (background, at capacity)
209
209
  [*] --> running : spawn (foreground or under limit)
210
210
  queued --> running : capacity available
211
+ queued --> stopped : stopped before admission
211
212
  running --> completed : all turns finished
212
213
  running --> error : unhandled exception
213
214
  running --> aborted : abort() called
@@ -233,6 +234,10 @@ stateDiagram-v2
233
234
  Note: `markStopped` always succeeds regardless of current status.
234
235
  Other terminal transitions guard against overwriting `stopped` — once an agent is stopped, only `resetForResume` can return it to `running`.
235
236
 
237
+ Terminal outcomes also carry orthogonal consumption state. Foreground delivery, `get_subagent_result`, and a queued completion notification mark the outcome consumed. Records remain available for the parent session; only their heavy live child sessions are released after the configured consumed or unconsumed retention window. Released records keep their result and persisted transcript pointer but cannot resume.
238
+
239
+ Completion notifications are held while the parent agent run is active and flushed on `agent_settled`, rechecking consumption before enqueueing a follow-up. Child session creation shares the parent model runtime and leaves extension-tool registration open; a denylist removes disallowed built-ins and recursive orchestration tools across registry refreshes.
240
+
236
241
  ## Execution flow
237
242
 
238
243
  ```mermaid
@@ -265,7 +270,7 @@ sequenceDiagram
265
270
  Ag-->>Mgr: update Subagent
266
271
  Mgr-->>Tool: Subagent
267
272
  Tool-->>LLM: formatted result
268
- Note over Mgr: disposeSession() fires `disposed` at cleanup (resume-detectable)
273
+ Note over Mgr: retention releases heavy sessions but keeps terminal records and transcript pointers
269
274
  ```
270
275
 
271
276
  ## Module organization
@@ -287,7 +292,7 @@ src/
287
292
 
288
293
  ├── config/ agent type definitions and resolution
289
294
  │ ├── agent-types.ts AgentTypeRegistry class
290
- │ ├── default-agents.ts built-in agent configs (general-purpose, Explore, Plan)
295
+ │ ├── default-agents.ts built-in agent configs (general-purpose, Explore)
291
296
  │ ├── custom-agents.ts user-defined agent .md file loader
292
297
  │ └── invocation-config.ts per-call config merge
293
298
 
@@ -481,6 +486,7 @@ The core emits events on `pi.events` that any extension can observe:
481
486
  | --------------------- | ----------------------------------------------------------------------------------- | --------------------------------------------- |
482
487
  | `subagents:started` | `{ id, type, description }` | Agent begins running |
483
488
  | `subagents:completed` | `{ id, type, description, status, result?, error?, toolUses, durationMs, tokens? }` | Agent finishes successfully |
489
+ | `subagents:resumed` | same as `completed` (`buildEventData` shape) | A retained session's resumed turn finishes |
484
490
  | `subagents:failed` | same as `completed` (`buildEventData` shape) | Agent ends in `error`/`stopped`/`aborted` |
485
491
  | `subagents:compacted` | `{ id, type, description, reason, tokensBefore, compactionCount }` | Child session compacts |
486
492
  | `subagents:created` | `{ id, type, description, isBackground }` | Background agent created (pre-admission) |
@@ -943,21 +949,7 @@ Directory organization is healthy (seven domain directories, six root files) —
943
949
 
944
950
  #### ✅ Step 1 — Extract result delivery from `Subagent` ([#535])
945
951
 
946
- Smell: Category C (anemic domain / misplaced state, Law of Demeter, scattered resets) the result-delivery domain named in the first-principles refinement is still fused into the execution record.
947
- Target files:
948
-
949
- - `src/lifecycle/subagent.ts` — drop `_notification` / `notification`; stop constructing `NotificationState` from `parentSession.toolCallId`.
950
- - `src/observation/notification.ts` — `NotificationManager` owns consumed-state keyed by agent id behind a single tell operation (e.g. `consume(id)`) that also cancels the pending nudge.
951
- - `src/observation/notification-state.ts` — dissolve into the manager or move wholly into the observation domain.
952
- - `src/observation/subagent-events-observer.ts`, `src/tools/get-result-tool.ts` — call the new delivery interface instead of reaching through the record.
953
-
954
- The `toolCallId` needed by `formatTaskNotification` already travels on `execution.parentSession`; expose it without routing through a notification object.
955
- The pre-await consumption ordering (the "Bug 1" race tests in `test/lifecycle/subagent-manager.test.ts`) is a preserved invariant — consuming before awaiting must still suppress the completion nudge.
956
-
957
- Outcome: zero `record.notification?.` reach-throughs in `src/`; `Subagent` carries no notification field; delivery state lives in the observation domain.
958
-
959
- Landed: `notification-state.ts` deleted; `Subagent.toolCallId` getter added over `execution.parentSession`; `NotificationManager` owns `consumed: Set<string>` behind one `consume(id)` tell that adds to the set and cancels the pending nudge atomically.
960
- Collapsing the old two-step reset (`markConsumed()` + `cancelNudge()`) into one atomic operation structurally eliminates the historical "Bug 1" race rather than just reordering it — `consume()` now suppresses the nudge regardless of whether it runs before or after the completion promise resolves, as long as it runs within the 200 ms hold window.
952
+ Result delivery evolved twice. `notification-state.ts` was first dissolved and `Subagent.toolCallId` moved to execution identity. Consumption now lives as domain state on `SubagentState`, where retention and every push/pull delivery path can consult it. `NotificationManager` owns only delivery timing: it withholds records during a parent run and rechecks consumption at `agent_settled`, eliminating the uncancellable follow-up race rather than relying on a timer window.
961
953
 
962
954
  `Release: batch "result-delivery"`
963
955