@nklisch/pi-enhanced 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/node_modules/@nklisch/pi-clearance/README.md +10 -5
- package/node_modules/@nklisch/pi-clearance/docs/ARCHITECTURE.md +8 -5
- package/node_modules/@nklisch/pi-clearance/docs/CONFIGURATION.md +25 -35
- package/node_modules/@nklisch/pi-clearance/docs/DEVELOPER_GUIDE.md +13 -11
- package/node_modules/@nklisch/pi-clearance/docs/PACK_AUTHORING.md +5 -4
- package/node_modules/@nklisch/pi-clearance/docs/PRINCIPLES.md +14 -10
- package/node_modules/@nklisch/pi-clearance/docs/REFERENCE_PATTERNS.md +1 -1
- package/node_modules/@nklisch/pi-clearance/docs/REVIEWER_PROMPTS.md +12 -8
- package/node_modules/@nklisch/pi-clearance/docs/RULE_PACKS.md +1 -1
- package/node_modules/@nklisch/pi-clearance/docs/SPEC.md +7 -6
- package/node_modules/@nklisch/pi-clearance/docs/TUNE.md +2 -2
- package/node_modules/@nklisch/pi-clearance/docs/USER_GUIDE.md +7 -3
- package/node_modules/@nklisch/pi-clearance/docs/VISION.md +3 -3
- package/node_modules/@nklisch/pi-clearance/native/clearance-core.darwin-x64.node +0 -0
- package/node_modules/@nklisch/pi-clearance/native/clearance-core.linux-arm64-gnu.node +0 -0
- package/node_modules/@nklisch/pi-clearance/native/clearance-core.win32-arm64-msvc.node +0 -0
- package/node_modules/@nklisch/pi-clearance/native/clearance-core.win32-x64-msvc.node +0 -0
- package/node_modules/@nklisch/pi-clearance/package.json +9 -5
- package/node_modules/@nklisch/pi-clearance/src/config/config-command-plans.ts +79 -3
- package/node_modules/@nklisch/pi-clearance/src/config/config-command-writer.ts +7 -1
- package/node_modules/@nklisch/pi-clearance/src/config/defaults.ts +42 -0
- package/node_modules/@nklisch/pi-clearance/src/config/gated-tools.ts +7 -0
- package/node_modules/@nklisch/pi-clearance/src/config/loader.ts +7 -1
- package/node_modules/@nklisch/pi-clearance/src/config/pack-enablement-writer.ts +1 -0
- package/node_modules/@nklisch/pi-clearance/src/config/paths.ts +14 -3
- package/node_modules/@nklisch/pi-clearance/src/config/persistence.ts +135 -0
- package/node_modules/@nklisch/pi-clearance/src/config/schema.ts +74 -26
- package/node_modules/@nklisch/pi-clearance/src/contracts/AdversarialCase.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/AdversarialCaseCategory.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/AdversarialCaseExpectation.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/AdversarialCaseResult.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/AdversarialCaseResultOutcome.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/AdversarialCaseSource.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/AdversarialValidationReport.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/AdversarialValidationStatus.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/BashBlock.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/BashCommandShape.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/BashConditionalArm.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/BashControlConstruct.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/BashFlag.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/BashForLoopKeywordSpans.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/BashIteratorEntry.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/BashIteratorEntryKind.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/BashListOperator.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/BashLoopVariableReference.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/BashPathFact.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/BashPathFactContext.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/BashPathFactProvenance.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/BashPathFactProvenanceEntry.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/BashPathFacts.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/BashPipeline.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/BashStage.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/BashStageProgram.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/BlockOperator.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/CapturedOutcome.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/CommandFamilyKey.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/CommandFamilySummary.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/CompileError.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/CompositionOperator.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/CompoundBodyReason.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/CompoundFeatureReason.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/CompoundForm.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/CompoundIteratorReason.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/CorpusEntry.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/CorpusExpectedLabel.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/CorpusFidelity.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/CorpusQueryModel.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/CorpusQuerySummary.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/CorpusQuerySummarySnapshot.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/CorpusRecord.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/CorpusSource.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/CountByLabel.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/Decision.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/DecisionEffect.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/DecisionProvenance.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/DecisionSource.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/DiagnosticSeverity.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/EffectivePolicy.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/EmbeddedShellProjection.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/EnvironmentAssignment.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/IteratorSourceKind.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/LoopQuoteKind.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/LoopVariableUnknownReason.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/MatcherExpr.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/MutationShapeKind.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/MutationTrustBoundaryClassification.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/MutationTrustBoundaryKind.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/PackCompileResult.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/PackWarningLevel.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ParsedEvidence.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ParsedShapeSummary.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/PathAccess.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/PathFactProjectScope.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/PathFactsRequirement.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/PathFactsResolvedConfig.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/PathNormalization.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/PathScope.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/PathScopeMatcherExpr.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/PathScopeMatcherMode.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/PathUnknownReason.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/PathUsageKind.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/PiBuiltinToolOperation.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/PiBuiltinToolPathInput.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/PiBuiltinToolShape.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/PiBuiltinToolSpec.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/PiFileMutationToolName.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/PiToolMutationFacts.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/PolicyPack.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/PolicyPackDocLink.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/PolicyPackExample.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/PolicyPackMetadata.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/PolicyPackWarning.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/PolicyRule.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ProposalNotRunReason.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ProposalNotRunSeverity.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/QuoteKind.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/Redirect.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/RedirectStream.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/RedirectTargetKind.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayCorpus.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayDelta.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayDeltaBlockedSummary.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayDeltaChangedRecord.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayDeltaFamily.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayDeltaImprovement.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayDeltaRegression.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayDeltaStatus.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayDeltaTransitionCount.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayPathFacts.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayReviewerMode.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayReviewerOutcome.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayStatus.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ReplayedDecision.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ShapeDiagnostic.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/SourceFidelity.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/SourceSpan.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/Substitution.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/SubstitutionKind.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ToolCallIdentity.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ToolPathAccess.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ToolPathFact.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ToolPathFactContext.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ToolPathFacts.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ToolPathUsage.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/ToolShape.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/UnknownPathBehavior.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/UnknownToolShape.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/contracts/index.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/index.ts +33 -2
- package/node_modules/@nklisch/pi-clearance/src/native/loader.ts +12 -6
- package/node_modules/@nklisch/pi-clearance/src/replay/reviewer-config-proposals.ts +7 -4
- package/node_modules/@nklisch/pi-clearance/src/runtime/allow-request-message.ts +21 -0
- package/node_modules/@nklisch/pi-clearance/src/runtime/auto-reviewer-read-models.ts +165 -8
- package/node_modules/@nklisch/pi-clearance/src/runtime/command-registry.ts +1 -1
- package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/allow.ts +26 -2
- package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/packs.ts +6 -6
- package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/scope.ts +5 -5
- package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings/actions.ts +11 -0
- package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings/dispatcher.ts +274 -1
- package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings/model-options.ts +52 -0
- package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings/native-ui.ts +54 -67
- package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings/panels/reviewer.ts +19 -3
- package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings/panels/scope.ts +2 -11
- package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings/panels.ts +10 -1
- package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings/read-model.ts +47 -13
- package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/settings.ts +32 -37
- package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/status.ts +3 -0
- package/node_modules/@nklisch/pi-clearance/src/runtime/config-commands/types.ts +14 -5
- package/node_modules/@nklisch/pi-clearance/src/runtime/handler.ts +36 -0
- package/node_modules/@nklisch/pi-clearance/src/runtime/mode-prompt.ts +0 -1
- package/node_modules/@nklisch/pi-clearance/src/runtime/model-adapter.ts +5 -1
- package/node_modules/@nklisch/pi-clearance/src/runtime/reviewer-context.ts +73 -10
- package/node_modules/@nklisch/pi-clearance/src/runtime/reviewer-prompts.ts +186 -175
- package/node_modules/@nklisch/pi-clearance/src/runtime/reviewer.ts +26 -6
- package/node_modules/@nklisch/pi-plugins/dist/infrastructure/state/local-lock-filesystem.d.ts +23 -1
- package/node_modules/@nklisch/pi-plugins/dist/infrastructure/state/local-lock-filesystem.js +46 -50
- package/node_modules/@nklisch/pi-plugins/dist/infrastructure/state/local-lock-filesystem.js.map +1 -1
- package/node_modules/@nklisch/pi-plugins/dist/runtime/mcp/pi-mcp-adapter-package.js +2 -2
- package/node_modules/@nklisch/pi-plugins/dist/runtime/mcp/pi-mcp-adapter-package.js.map +1 -1
- package/node_modules/@nklisch/pi-plugins/dist/runtime/mcp/pi-mcp-adapter-runtime.js +2 -2
- package/node_modules/@nklisch/pi-plugins/dist/runtime/mcp/pi-mcp-adapter-runtime.js.map +1 -1
- package/node_modules/@nklisch/pi-plugins/dist/runtime/subagents/pi-subagents-lifecycle.js +1 -1
- package/node_modules/@nklisch/pi-plugins/dist/runtime/subagents/pi-subagents-package.js +2 -2
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/README.md +41 -31
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/dist/public.d.ts +2 -1
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/FORK-MAINTENANCE.md +17 -11
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/VISION.md +14 -7
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/architecture/architecture.md +11 -19
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/docs/comparison-with-upstream.md +58 -53
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/package.json +2 -2
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/config/agent-type-resolution.ts +43 -0
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/config/agent-types.ts +11 -6
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/config/custom-agents.ts +13 -6
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/config/default-agents.ts +0 -52
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/config/thinking-levels.ts +12 -0
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/handlers/interrupt.ts +5 -2
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/handlers/lifecycle.ts +3 -3
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/index.ts +7 -6
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/create-subagent-session.ts +7 -2
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/parent-snapshot.ts +11 -3
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/subagent-manager.ts +26 -56
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/subagent-session.ts +48 -9
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/subagent-state.ts +32 -0
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/lifecycle/subagent.ts +105 -17
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/observation/composite-subagent-observer.ts +4 -0
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/observation/notification.ts +50 -46
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/observation/renderer.ts +1 -1
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/observation/subagent-events-observer.ts +15 -0
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/runtime.ts +2 -0
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/service/service-adapter.ts +35 -6
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/service/service.ts +1 -0
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/session/model-label.ts +19 -0
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/session/prompts.ts +24 -1
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/session/session-config.ts +11 -6
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/settings.ts +70 -3
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/tools/agent-tool.ts +27 -10
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/tools/background-spawner.ts +6 -2
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/tools/foreground-runner.ts +12 -3
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/tools/get-result-report.ts +17 -3
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/tools/get-result-tool.ts +13 -20
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/tools/result-renderer.ts +6 -1
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/tools/spawn-config.ts +16 -16
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/tools/steer-tool.ts +12 -4
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/types.ts +2 -2
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/ui/agent-widget.ts +24 -11
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/ui/display.ts +10 -7
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/ui/glyphs.ts +7 -0
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/ui/session-navigation.ts +34 -25
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/ui/session-navigator.ts +30 -10
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/ui/subagents-settings.ts +58 -13
- package/node_modules/@nklisch/pi-plugins/node_modules/@nklisch/pi-subagents/src/ui/widget-renderer.ts +32 -19
- package/node_modules/@nklisch/pi-plugins/package.json +3 -3
- package/package.json +1 -1
- package/test/verify-bundle.mjs +4 -0
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
|
|
3
|
+
import { DEFAULT_PROJECT_SCOPE_BEHAVIOR } from "./defaults.ts";
|
|
4
|
+
import { isExactNonBashToolName } from "./gated-tools.ts";
|
|
3
5
|
import type { JsonPatchOperation } from "../replay/proposal-schema.ts";
|
|
4
6
|
import { isHighCostReviewerModel } from "../runtime/reviewer-model.ts";
|
|
5
7
|
import type {
|
|
@@ -91,10 +93,12 @@ export function inferScopePreset(
|
|
|
91
93
|
const fields = SCOPE_PRESET_FIELDS[preset];
|
|
92
94
|
if (
|
|
93
95
|
scope.safeHomeUseDefaults === fields.safeHomeUseDefaults &&
|
|
94
|
-
(scope.agentSupportUseDefaults
|
|
96
|
+
(scope.agentSupportUseDefaults !== false) ===
|
|
95
97
|
fields.agentSupportUseDefaults &&
|
|
96
|
-
(scope.homePathBehavior ??
|
|
97
|
-
|
|
98
|
+
(scope.homePathBehavior ?? DEFAULT_PROJECT_SCOPE_BEHAVIOR.homePathBehavior) ===
|
|
99
|
+
fields.homePathBehavior &&
|
|
100
|
+
(scope.sensitivePathBehavior ??
|
|
101
|
+
DEFAULT_PROJECT_SCOPE_BEHAVIOR.sensitivePathBehavior) ===
|
|
98
102
|
fields.sensitivePathBehavior &&
|
|
99
103
|
scope.unknownPathBehavior === fields.unknownPathBehavior
|
|
100
104
|
) {
|
|
@@ -137,6 +141,10 @@ export type ReviewNoteDisplayCommandChange =
|
|
|
137
141
|
| { readonly kind: "show-model-label"; readonly enabled: boolean }
|
|
138
142
|
| { readonly kind: "accent"; readonly enabled: boolean };
|
|
139
143
|
|
|
144
|
+
export type GatedToolCommandChange =
|
|
145
|
+
| { readonly kind: "add"; readonly toolName: string }
|
|
146
|
+
| { readonly kind: "remove"; readonly toolName: string };
|
|
147
|
+
|
|
140
148
|
export type ReviewerCommandChange =
|
|
141
149
|
| { readonly kind: "prompt-posture"; readonly promptPosture: string }
|
|
142
150
|
| { readonly kind: "context-mode"; readonly contextMode: ReviewerContextMode }
|
|
@@ -181,6 +189,74 @@ export type PlanProjectScopeCommandChangeResult =
|
|
|
181
189
|
}
|
|
182
190
|
| { readonly ok: false; readonly reason: string };
|
|
183
191
|
|
|
192
|
+
export function planGatedToolCommandChange(input: {
|
|
193
|
+
readonly change: GatedToolCommandChange;
|
|
194
|
+
readonly resolvedConfig: ResolvedConfig;
|
|
195
|
+
}):
|
|
196
|
+
| { readonly ok: true; readonly plan: ConfigCommandPlan }
|
|
197
|
+
| { readonly ok: false; readonly reason: string } {
|
|
198
|
+
const toolName = input.change.toolName;
|
|
199
|
+
if (!isExactNonBashToolName(toolName)) {
|
|
200
|
+
return {
|
|
201
|
+
ok: false,
|
|
202
|
+
reason:
|
|
203
|
+
"gatedTools accepts exact non-Bash tool names only; wildcards, whitespace, and bash are not allowed",
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const snapshots = input.resolvedConfig.sourceSnapshots;
|
|
208
|
+
if (snapshots === undefined) {
|
|
209
|
+
return {
|
|
210
|
+
ok: false,
|
|
211
|
+
reason:
|
|
212
|
+
"resolved config did not include source snapshots; reload config before planning a gated-tool write",
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const before = cloneJsonish({
|
|
217
|
+
...snapshots.global,
|
|
218
|
+
gatedTools: [...(snapshots.global.gatedTools ?? [])],
|
|
219
|
+
});
|
|
220
|
+
const after = cloneJsonish(before) as Mutable<GlobalConfig>;
|
|
221
|
+
const current = [...before.gatedTools];
|
|
222
|
+
const next =
|
|
223
|
+
input.change.kind === "add"
|
|
224
|
+
? current.includes(toolName)
|
|
225
|
+
? current
|
|
226
|
+
: [...current, toolName]
|
|
227
|
+
: current.filter((candidate) => candidate !== toolName);
|
|
228
|
+
after.gatedTools = next;
|
|
229
|
+
const patch = fieldPatch("/gatedTools", current, next);
|
|
230
|
+
const title =
|
|
231
|
+
input.change.kind === "add"
|
|
232
|
+
? `Gate non-Bash tool ${toolName}`
|
|
233
|
+
: `Stop gating non-Bash tool ${toolName}`;
|
|
234
|
+
const planWithoutId = {
|
|
235
|
+
target: { kind: "global", path: snapshots.paths.globalConfigFile },
|
|
236
|
+
title,
|
|
237
|
+
summary:
|
|
238
|
+
patch.length === 0
|
|
239
|
+
? `${title}; no config write is needed.`
|
|
240
|
+
: `${title}; only this exact tool name will use Clearance analysis and policy.`,
|
|
241
|
+
patch,
|
|
242
|
+
before,
|
|
243
|
+
after,
|
|
244
|
+
requiredAcknowledgementCodes: [],
|
|
245
|
+
warnings: [],
|
|
246
|
+
} satisfies Omit<ConfigCommandPlan, "id">;
|
|
247
|
+
|
|
248
|
+
return {
|
|
249
|
+
ok: true,
|
|
250
|
+
plan: {
|
|
251
|
+
id: deterministicPlanId({
|
|
252
|
+
gatedToolChange: input.change,
|
|
253
|
+
...planWithoutId,
|
|
254
|
+
}),
|
|
255
|
+
...planWithoutId,
|
|
256
|
+
},
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
184
260
|
export function planModeCommandChange(input: {
|
|
185
261
|
readonly mode: ClearanceMode;
|
|
186
262
|
readonly resolvedConfig: ResolvedConfig;
|
|
@@ -12,6 +12,10 @@ import type { TSchema } from "@sinclair/typebox";
|
|
|
12
12
|
|
|
13
13
|
import type { JsonPatchOperation } from "../replay/proposal-schema.ts";
|
|
14
14
|
import type { ResolvedConfig } from "./loader.ts";
|
|
15
|
+
import {
|
|
16
|
+
type ConfigPersistenceKind,
|
|
17
|
+
serializeSparseConfigText,
|
|
18
|
+
} from "./persistence.ts";
|
|
15
19
|
import {
|
|
16
20
|
type GlobalConfig,
|
|
17
21
|
GlobalConfigSchema,
|
|
@@ -101,6 +105,7 @@ export type ConfigCommandApplyResult =
|
|
|
101
105
|
interface AtomicConfigWriteInput {
|
|
102
106
|
readonly planId: string;
|
|
103
107
|
readonly targetPath: string;
|
|
108
|
+
readonly configKind: ConfigPersistenceKind;
|
|
104
109
|
readonly value: GlobalConfig | ProjectOverlayConfig;
|
|
105
110
|
readonly hadExistingFile: boolean;
|
|
106
111
|
readonly reloadConfig: () => Promise<ResolvedConfig>;
|
|
@@ -184,6 +189,7 @@ export async function applyConfigCommandPlan(
|
|
|
184
189
|
return await writeConfigTargetAndValidate({
|
|
185
190
|
planId: plan.id,
|
|
186
191
|
targetPath: plan.target.path,
|
|
192
|
+
configKind: plan.target.kind,
|
|
187
193
|
value: patched.value,
|
|
188
194
|
hadExistingFile: readResult.exists,
|
|
189
195
|
reloadConfig: dependencies.reloadConfig,
|
|
@@ -207,7 +213,7 @@ export async function writeConfigTargetAndValidate(
|
|
|
207
213
|
await mkdir(path.dirname(input.targetPath), { recursive: true });
|
|
208
214
|
await writeFile(
|
|
209
215
|
tempPath,
|
|
210
|
-
|
|
216
|
+
serializeSparseConfigText(input.configKind, input.value),
|
|
211
217
|
"utf8",
|
|
212
218
|
);
|
|
213
219
|
tempPresent = true;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User-visible defaults shared by schema normalization and status/read models.
|
|
3
|
+
* Keeping these values in one module prevents a new schema default from being
|
|
4
|
+
* mistaken for a customization by diagnostics.
|
|
5
|
+
*/
|
|
6
|
+
export const DEFAULT_REVIEWER_PROMPT_POSTURE = "reviewer.default" as const;
|
|
7
|
+
export const DEFAULT_REVIEWER_CONTEXT_MODE = "recentContext" as const;
|
|
8
|
+
|
|
9
|
+
export const DEFAULT_REVIEWER_TOKEN_BUDGET = {
|
|
10
|
+
window: "24h",
|
|
11
|
+
limit: null,
|
|
12
|
+
} as const;
|
|
13
|
+
|
|
14
|
+
export const DEFAULT_REVIEWER_RECENT_CONTEXT = {
|
|
15
|
+
decisionLimit: 25,
|
|
16
|
+
decisionWindow: "2h",
|
|
17
|
+
conversationTurns: 3,
|
|
18
|
+
userTurns: 5,
|
|
19
|
+
conversationCharLimit: 6000,
|
|
20
|
+
} as const;
|
|
21
|
+
|
|
22
|
+
export const DEFAULT_REVIEWER_ESCALATION = {
|
|
23
|
+
enabled: true,
|
|
24
|
+
denialLimit: 3,
|
|
25
|
+
window: "10m",
|
|
26
|
+
} as const;
|
|
27
|
+
|
|
28
|
+
export const DEFAULT_UNKNOWN_TOOL_POSTURE = "allow" as const;
|
|
29
|
+
|
|
30
|
+
export const DEFAULT_PROJECT_SCOPE_BEHAVIOR = {
|
|
31
|
+
safeHomeUseDefaults: true,
|
|
32
|
+
agentSupportUseDefaults: true,
|
|
33
|
+
unknownPathBehavior: "review",
|
|
34
|
+
sensitivePathBehavior: "review",
|
|
35
|
+
homePathBehavior: "allow",
|
|
36
|
+
} as const;
|
|
37
|
+
|
|
38
|
+
export const DEFAULT_REVIEW_NOTE_DISPLAY = {
|
|
39
|
+
mode: "reason+accent",
|
|
40
|
+
showModelLabel: false,
|
|
41
|
+
accent: true,
|
|
42
|
+
} as const;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Exact-name syntax for the global non-Bash Clearance opt-in list. */
|
|
2
|
+
export const EXACT_NON_BASH_TOOL_NAME_PATTERN =
|
|
3
|
+
"^(?!bash$)[^\\s*?\\[\\]{}]+$" as const;
|
|
4
|
+
|
|
5
|
+
export function isExactNonBashToolName(value: string): boolean {
|
|
6
|
+
return value.length > 0 && new RegExp(EXACT_NON_BASH_TOOL_NAME_PATTERN).test(value);
|
|
7
|
+
}
|
|
@@ -3,6 +3,7 @@ import { homedir, tmpdir } from "node:os";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import type { Static, TSchema } from "@sinclair/typebox";
|
|
5
5
|
import type { DecisionEffect } from "../policy/core.ts";
|
|
6
|
+
import { DEFAULT_UNKNOWN_TOOL_POSTURE } from "./defaults.ts";
|
|
6
7
|
import {
|
|
7
8
|
isHighCostReviewerModel,
|
|
8
9
|
parseModelSpec,
|
|
@@ -69,6 +70,7 @@ export interface ResolvedReviewerConfig {
|
|
|
69
70
|
readonly decisionLimit: number;
|
|
70
71
|
readonly decisionWindow: string;
|
|
71
72
|
readonly conversationTurns: number;
|
|
73
|
+
readonly userTurns?: number;
|
|
72
74
|
readonly conversationCharLimit: number;
|
|
73
75
|
};
|
|
74
76
|
readonly escalation: {
|
|
@@ -133,6 +135,8 @@ export interface ResolvedConfig {
|
|
|
133
135
|
*/
|
|
134
136
|
readonly sourceSnapshots?: ResolvedConfigSourceSnapshots;
|
|
135
137
|
readonly mode: ClearanceMode;
|
|
138
|
+
/** Exact non-Bash tool names explicitly opted into Clearance gating. */
|
|
139
|
+
readonly gatedTools?: readonly string[];
|
|
136
140
|
readonly unknownToolPosture: DecisionEffect;
|
|
137
141
|
readonly projectScope: ResolvedProjectScope;
|
|
138
142
|
readonly packEnablement: ResolvedPackEnablement;
|
|
@@ -250,7 +254,9 @@ export async function loadConfig(
|
|
|
250
254
|
repository: repositoryPolicy,
|
|
251
255
|
},
|
|
252
256
|
mode,
|
|
253
|
-
|
|
257
|
+
gatedTools: [...globalConfig.gatedTools],
|
|
258
|
+
unknownToolPosture:
|
|
259
|
+
globalConfig.unknownToolPosture ?? DEFAULT_UNKNOWN_TOOL_POSTURE,
|
|
254
260
|
projectScope: projectScopeResolution.scope,
|
|
255
261
|
packEnablement,
|
|
256
262
|
globalPacks: withPackSource(globalConfig.packs, "user-global"),
|
|
@@ -113,6 +113,7 @@ export async function applyPackEnablementPlan(
|
|
|
113
113
|
return await writeConfigTargetAndValidate({
|
|
114
114
|
planId: plan.id,
|
|
115
115
|
targetPath: plan.targetPath,
|
|
116
|
+
configKind: plan.request.scope,
|
|
116
117
|
value: patched.value,
|
|
117
118
|
hadExistingFile: readResult.exists,
|
|
118
119
|
reloadConfig: dependencies.reloadConfig,
|
|
@@ -12,12 +12,18 @@ export interface ConfigPaths {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export function resolveUserConfigRoot(): string {
|
|
15
|
-
|
|
15
|
+
// Read the environment explicitly so isolated callers honor the process
|
|
16
|
+
// environment even when os.homedir() is cached.
|
|
17
|
+
const home = firstNonEmpty(
|
|
18
|
+
process.env.HOME,
|
|
19
|
+
process.env.USERPROFILE,
|
|
20
|
+
) ?? homedir();
|
|
16
21
|
|
|
17
22
|
switch (process.platform) {
|
|
18
23
|
case "win32":
|
|
19
24
|
return path.join(
|
|
20
|
-
process.env.LOCALAPPDATA ??
|
|
25
|
+
firstNonEmpty(process.env.LOCALAPPDATA) ??
|
|
26
|
+
path.join(home, "AppData", "Local"),
|
|
21
27
|
"pi",
|
|
22
28
|
"pi-clearance",
|
|
23
29
|
);
|
|
@@ -31,13 +37,18 @@ export function resolveUserConfigRoot(): string {
|
|
|
31
37
|
);
|
|
32
38
|
default:
|
|
33
39
|
return path.join(
|
|
34
|
-
process.env.XDG_CONFIG_HOME ??
|
|
40
|
+
firstNonEmpty(process.env.XDG_CONFIG_HOME) ??
|
|
41
|
+
path.join(home, ".config"),
|
|
35
42
|
"pi",
|
|
36
43
|
"pi-clearance",
|
|
37
44
|
);
|
|
38
45
|
}
|
|
39
46
|
}
|
|
40
47
|
|
|
48
|
+
function firstNonEmpty(...values: readonly (string | undefined)[]): string | undefined {
|
|
49
|
+
return values.find((value) => value !== undefined && value.length > 0);
|
|
50
|
+
}
|
|
51
|
+
|
|
41
52
|
export function projectKeyFor(cwd: string): string {
|
|
42
53
|
const absolute = path.resolve(cwd);
|
|
43
54
|
const hash = createHash("sha256").update(absolute).digest("hex").slice(0, 8);
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CONFIG_SCHEMA_VERSION,
|
|
3
|
+
type GlobalConfig,
|
|
4
|
+
GlobalConfigSchema,
|
|
5
|
+
normalizeConfig,
|
|
6
|
+
type ProjectOverlayConfig,
|
|
7
|
+
ProjectOverlaySchema,
|
|
8
|
+
} from "./schema.ts";
|
|
9
|
+
|
|
10
|
+
export type ConfigPersistenceKind = "global" | "project";
|
|
11
|
+
export type NormalizedConfig = GlobalConfig | ProjectOverlayConfig;
|
|
12
|
+
|
|
13
|
+
/** The only JSON shape emitted for user-owned Clearance config files. */
|
|
14
|
+
export type SparseConfigDocument = Readonly<Record<string, unknown>> & {
|
|
15
|
+
readonly version: typeof CONFIG_SCHEMA_VERSION;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const OMIT = Symbol("omit-default");
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Serialize a schema-normalized runtime config without materializing defaults.
|
|
22
|
+
*
|
|
23
|
+
* Defaults are obtained by normalizing the schema's version-only seed rather
|
|
24
|
+
* than copied here. Objects are compacted recursively; arrays are semantic
|
|
25
|
+
* values and are retained as a whole whenever they differ from their default.
|
|
26
|
+
*/
|
|
27
|
+
export function serializeSparseConfig(
|
|
28
|
+
kind: ConfigPersistenceKind,
|
|
29
|
+
config: NormalizedConfig,
|
|
30
|
+
): SparseConfigDocument {
|
|
31
|
+
const defaults = normalizedDefaults(kind);
|
|
32
|
+
const compacted = compactValue(config, defaults);
|
|
33
|
+
const document: Record<string, unknown> = {
|
|
34
|
+
version: config.version,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
if (isRecord(compacted)) {
|
|
38
|
+
for (const [key, value] of Object.entries(compacted)) {
|
|
39
|
+
if (key !== "version") {
|
|
40
|
+
document[key] = value;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return canonicalize(document) as SparseConfigDocument;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Return the canonical on-disk representation for a normalized config. */
|
|
49
|
+
export function serializeSparseConfigText(
|
|
50
|
+
kind: ConfigPersistenceKind,
|
|
51
|
+
config: NormalizedConfig,
|
|
52
|
+
): string {
|
|
53
|
+
return `${JSON.stringify(serializeSparseConfig(kind, config), null, 2)}\n`;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function normalizedDefaults(kind: ConfigPersistenceKind): NormalizedConfig {
|
|
57
|
+
const schema = kind === "global" ? GlobalConfigSchema : ProjectOverlaySchema;
|
|
58
|
+
const result = normalizeConfig(schema, { version: CONFIG_SCHEMA_VERSION });
|
|
59
|
+
if (!result.ok) {
|
|
60
|
+
throw new Error(`failed to normalize ${kind} config defaults`);
|
|
61
|
+
}
|
|
62
|
+
return result.value;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function compactValue(value: unknown, defaults: unknown): unknown {
|
|
66
|
+
if (jsonEqual(value, defaults)) {
|
|
67
|
+
return OMIT;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (Array.isArray(value)) {
|
|
71
|
+
return value.map((entry) => cloneJsonish(entry));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (isRecord(value)) {
|
|
75
|
+
const defaultRecord = isRecord(defaults) ? defaults : undefined;
|
|
76
|
+
const compacted: Record<string, unknown> = {};
|
|
77
|
+
for (const key of orderedKeys(Object.keys(value))) {
|
|
78
|
+
const child = compactValue(value[key], defaultRecord?.[key]);
|
|
79
|
+
if (child !== OMIT) {
|
|
80
|
+
compacted[key] = child;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return Object.keys(compacted).length === 0 ? OMIT : compacted;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return value;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function canonicalize(value: unknown): unknown {
|
|
90
|
+
if (Array.isArray(value)) {
|
|
91
|
+
return value.map(canonicalize);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (isRecord(value)) {
|
|
95
|
+
const result: Record<string, unknown> = {};
|
|
96
|
+
for (const key of orderedKeys(Object.keys(value))) {
|
|
97
|
+
result[key] = canonicalize(value[key]);
|
|
98
|
+
}
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return value;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function orderedKeys(keys: readonly string[]): readonly string[] {
|
|
106
|
+
return [...keys].sort((left, right) => {
|
|
107
|
+
if (left === "version") return -1;
|
|
108
|
+
if (right === "version") return 1;
|
|
109
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function jsonEqual(left: unknown, right: unknown): boolean {
|
|
114
|
+
return (
|
|
115
|
+
JSON.stringify(canonicalize(left)) === JSON.stringify(canonicalize(right))
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function cloneJsonish<T>(value: T): T {
|
|
120
|
+
if (Array.isArray(value)) {
|
|
121
|
+
return value.map((entry) => cloneJsonish(entry)) as T;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (isRecord(value)) {
|
|
125
|
+
return Object.fromEntries(
|
|
126
|
+
Object.entries(value).map(([key, entry]) => [key, cloneJsonish(entry)]),
|
|
127
|
+
) as T;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return value;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
134
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
135
|
+
}
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
import { type Static, type TSchema, Type } from "@sinclair/typebox";
|
|
2
2
|
import { Value } from "@sinclair/typebox/value";
|
|
3
3
|
|
|
4
|
+
import {
|
|
5
|
+
DEFAULT_PROJECT_SCOPE_BEHAVIOR,
|
|
6
|
+
DEFAULT_REVIEWER_CONTEXT_MODE,
|
|
7
|
+
DEFAULT_REVIEWER_ESCALATION,
|
|
8
|
+
DEFAULT_REVIEWER_PROMPT_POSTURE,
|
|
9
|
+
DEFAULT_REVIEWER_RECENT_CONTEXT,
|
|
10
|
+
DEFAULT_REVIEWER_TOKEN_BUDGET,
|
|
11
|
+
DEFAULT_REVIEW_NOTE_DISPLAY,
|
|
12
|
+
DEFAULT_UNKNOWN_TOOL_POSTURE,
|
|
13
|
+
} from "./defaults.ts";
|
|
14
|
+
import { EXACT_NON_BASH_TOOL_NAME_PATTERN } from "./gated-tools.ts";
|
|
15
|
+
|
|
4
16
|
export const CONFIG_SCHEMA_VERSION = 1 as const;
|
|
5
17
|
|
|
6
18
|
const STRICT_OBJECT_OPTIONS = { additionalProperties: false } as const;
|
|
@@ -148,9 +160,11 @@ export const PolicyPackSchema = Type.Object(
|
|
|
148
160
|
|
|
149
161
|
export const ReviewNoteDisplaySchema = Type.Object(
|
|
150
162
|
{
|
|
151
|
-
mode: reviewNoteModeLiteral({ default:
|
|
152
|
-
showModelLabel: Type.Boolean({
|
|
153
|
-
|
|
163
|
+
mode: reviewNoteModeLiteral({ default: DEFAULT_REVIEW_NOTE_DISPLAY.mode }),
|
|
164
|
+
showModelLabel: Type.Boolean({
|
|
165
|
+
default: DEFAULT_REVIEW_NOTE_DISPLAY.showModelLabel,
|
|
166
|
+
}),
|
|
167
|
+
accent: Type.Boolean({ default: DEFAULT_REVIEW_NOTE_DISPLAY.accent }),
|
|
154
168
|
},
|
|
155
169
|
{ ...STRICT_OBJECT_OPTIONS, default: {} },
|
|
156
170
|
);
|
|
@@ -162,7 +176,7 @@ export const DisplayConfigSchema = Type.Object(
|
|
|
162
176
|
|
|
163
177
|
export const ReviewerConfigSchema = Type.Object(
|
|
164
178
|
{
|
|
165
|
-
promptPosture: Type.String({ default:
|
|
179
|
+
promptPosture: Type.String({ default: DEFAULT_REVIEWER_PROMPT_POSTURE }),
|
|
166
180
|
promptAppends: Type.Array(Type.String(), { default: [] }),
|
|
167
181
|
projectPromptAppends: Type.Array(Type.String(), { default: [] }),
|
|
168
182
|
promptOverride: Type.Union([Type.String(), Type.Null()], { default: null }),
|
|
@@ -171,41 +185,58 @@ export const ReviewerConfigSchema = Type.Object(
|
|
|
171
185
|
}),
|
|
172
186
|
tokenBudget: Type.Object(
|
|
173
187
|
{
|
|
174
|
-
window: Type.String({ default:
|
|
175
|
-
limit: Type.Union([Type.Number(), Type.Null()], {
|
|
188
|
+
window: Type.String({ default: DEFAULT_REVIEWER_TOKEN_BUDGET.window }),
|
|
189
|
+
limit: Type.Union([Type.Number(), Type.Null()], {
|
|
190
|
+
default: DEFAULT_REVIEWER_TOKEN_BUDGET.limit,
|
|
191
|
+
}),
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
...STRICT_OBJECT_OPTIONS,
|
|
195
|
+
default: DEFAULT_REVIEWER_TOKEN_BUDGET,
|
|
176
196
|
},
|
|
177
|
-
{ ...STRICT_OBJECT_OPTIONS, default: { window: "24h", limit: null } },
|
|
178
197
|
),
|
|
179
198
|
contextMode: Type.Union(
|
|
180
199
|
[Type.Literal("minimal"), Type.Literal("recentContext")],
|
|
181
|
-
{ default:
|
|
200
|
+
{ default: DEFAULT_REVIEWER_CONTEXT_MODE },
|
|
182
201
|
),
|
|
183
202
|
recentContext: Type.Object(
|
|
184
203
|
{
|
|
185
|
-
decisionLimit: Type.Integer({
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
204
|
+
decisionLimit: Type.Integer({
|
|
205
|
+
default: DEFAULT_REVIEWER_RECENT_CONTEXT.decisionLimit,
|
|
206
|
+
}),
|
|
207
|
+
decisionWindow: Type.String({
|
|
208
|
+
default: DEFAULT_REVIEWER_RECENT_CONTEXT.decisionWindow,
|
|
209
|
+
}),
|
|
210
|
+
conversationTurns: Type.Integer({
|
|
211
|
+
default: DEFAULT_REVIEWER_RECENT_CONTEXT.conversationTurns,
|
|
212
|
+
}),
|
|
213
|
+
userTurns: Type.Integer({
|
|
214
|
+
default: DEFAULT_REVIEWER_RECENT_CONTEXT.userTurns,
|
|
215
|
+
}),
|
|
216
|
+
conversationCharLimit: Type.Integer({
|
|
217
|
+
default: DEFAULT_REVIEWER_RECENT_CONTEXT.conversationCharLimit,
|
|
218
|
+
}),
|
|
189
219
|
},
|
|
190
220
|
{
|
|
191
221
|
...STRICT_OBJECT_OPTIONS,
|
|
192
222
|
default: {
|
|
193
|
-
|
|
194
|
-
decisionWindow: "2h",
|
|
195
|
-
conversationTurns: 3,
|
|
196
|
-
conversationCharLimit: 6000,
|
|
223
|
+
...DEFAULT_REVIEWER_RECENT_CONTEXT,
|
|
197
224
|
},
|
|
198
225
|
},
|
|
199
226
|
),
|
|
200
227
|
escalation: Type.Object(
|
|
201
228
|
{
|
|
202
|
-
enabled: Type.Boolean({
|
|
203
|
-
|
|
204
|
-
|
|
229
|
+
enabled: Type.Boolean({
|
|
230
|
+
default: DEFAULT_REVIEWER_ESCALATION.enabled,
|
|
231
|
+
}),
|
|
232
|
+
denialLimit: Type.Integer({
|
|
233
|
+
default: DEFAULT_REVIEWER_ESCALATION.denialLimit,
|
|
234
|
+
}),
|
|
235
|
+
window: Type.String({ default: DEFAULT_REVIEWER_ESCALATION.window }),
|
|
205
236
|
},
|
|
206
237
|
{
|
|
207
238
|
...STRICT_OBJECT_OPTIONS,
|
|
208
|
-
default:
|
|
239
|
+
default: DEFAULT_REVIEWER_ESCALATION,
|
|
209
240
|
},
|
|
210
241
|
),
|
|
211
242
|
},
|
|
@@ -227,14 +258,25 @@ export const PackEnablementSchema = Type.Object(
|
|
|
227
258
|
{ ...STRICT_OBJECT_OPTIONS, default: {} },
|
|
228
259
|
);
|
|
229
260
|
|
|
261
|
+
const GatedToolName = Type.String({
|
|
262
|
+
minLength: 1,
|
|
263
|
+
// Tool opt-in is deliberately exact-name only. Keep the field a strict
|
|
264
|
+
// schema boundary so wildcard/future-tool consent cannot slip into config.
|
|
265
|
+
pattern: EXACT_NON_BASH_TOOL_NAME_PATTERN,
|
|
266
|
+
});
|
|
267
|
+
|
|
230
268
|
export const GlobalConfigSchema = Type.Object(
|
|
231
269
|
{
|
|
232
270
|
version: Type.Literal(CONFIG_SCHEMA_VERSION),
|
|
233
271
|
mode: ClearanceModeLiteral,
|
|
272
|
+
gatedTools: Type.Array(GatedToolName, {
|
|
273
|
+
default: [],
|
|
274
|
+
uniqueItems: true,
|
|
275
|
+
}),
|
|
234
276
|
unknownToolPosture: Type.Optional(
|
|
235
277
|
Type.Union(
|
|
236
278
|
[Type.Literal("allow"), Type.Literal("deny"), Type.Literal("review")],
|
|
237
|
-
{ default:
|
|
279
|
+
{ default: DEFAULT_UNKNOWN_TOOL_POSTURE },
|
|
238
280
|
),
|
|
239
281
|
),
|
|
240
282
|
packs: Type.Array(PolicyPackSchema, { default: [] }),
|
|
@@ -263,13 +305,19 @@ export const ProjectScopeSchema = Type.Object(
|
|
|
263
305
|
tempDirectories: pathListSchema(),
|
|
264
306
|
deniedDirectories: pathListSchema(),
|
|
265
307
|
safeHomeDirectories: pathListSchema(),
|
|
266
|
-
safeHomeUseDefaults: Type.Boolean({
|
|
308
|
+
safeHomeUseDefaults: Type.Boolean({
|
|
309
|
+
default: DEFAULT_PROJECT_SCOPE_BEHAVIOR.safeHomeUseDefaults,
|
|
310
|
+
}),
|
|
267
311
|
/** Optional custom Pi support roots; built-in roots remain enabled by default. */
|
|
268
312
|
agentSupportDirectories: Type.Optional(pathListSchema()),
|
|
269
|
-
agentSupportUseDefaults: Type.Optional(
|
|
313
|
+
agentSupportUseDefaults: Type.Optional(
|
|
314
|
+
Type.Boolean({
|
|
315
|
+
default: DEFAULT_PROJECT_SCOPE_BEHAVIOR.agentSupportUseDefaults,
|
|
316
|
+
}),
|
|
317
|
+
),
|
|
270
318
|
unknownPathBehavior: Type.Union(
|
|
271
319
|
[Type.Literal("review"), Type.Literal("deny")],
|
|
272
|
-
{ default:
|
|
320
|
+
{ default: DEFAULT_PROJECT_SCOPE_BEHAVIOR.unknownPathBehavior },
|
|
273
321
|
),
|
|
274
322
|
/**
|
|
275
323
|
* Behavior for paths the engine classifies as sensitive home
|
|
@@ -278,7 +326,7 @@ export const ProjectScopeSchema = Type.Object(
|
|
|
278
326
|
*/
|
|
279
327
|
sensitivePathBehavior: Type.Union(
|
|
280
328
|
[Type.Literal("review"), Type.Literal("deny")],
|
|
281
|
-
{ default:
|
|
329
|
+
{ default: DEFAULT_PROJECT_SCOPE_BEHAVIOR.sensitivePathBehavior },
|
|
282
330
|
),
|
|
283
331
|
/**
|
|
284
332
|
* `"review"` claws back baseline home-scope read auto-allows so any
|
|
@@ -286,7 +334,7 @@ export const ProjectScopeSchema = Type.Object(
|
|
|
286
334
|
*/
|
|
287
335
|
homePathBehavior: Type.Union(
|
|
288
336
|
[Type.Literal("allow"), Type.Literal("review")],
|
|
289
|
-
{ default:
|
|
337
|
+
{ default: DEFAULT_PROJECT_SCOPE_BEHAVIOR.homePathBehavior },
|
|
290
338
|
),
|
|
291
339
|
},
|
|
292
340
|
{ ...STRICT_OBJECT_OPTIONS, default: {} },
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// @generated by ts-rs; do not edit. Run `
|
|
1
|
+
// @generated by ts-rs; do not edit. Run `npm run contracts:generate`.
|
|
2
2
|
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
|
3
3
|
import type { AdversarialCaseCategory } from "./AdversarialCaseCategory.ts";
|
|
4
4
|
import type { AdversarialCaseExpectation } from "./AdversarialCaseExpectation.ts";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// @generated by ts-rs; do not edit. Run `
|
|
1
|
+
// @generated by ts-rs; do not edit. Run `npm run contracts:generate`.
|
|
2
2
|
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
|
3
3
|
|
|
4
4
|
export type AdversarialCaseCategory =
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// @generated by ts-rs; do not edit. Run `
|
|
1
|
+
// @generated by ts-rs; do not edit. Run `npm run contracts:generate`.
|
|
2
2
|
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
|
3
3
|
|
|
4
4
|
export type AdversarialCaseExpectation =
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// @generated by ts-rs; do not edit. Run `
|
|
1
|
+
// @generated by ts-rs; do not edit. Run `npm run contracts:generate`.
|
|
2
2
|
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
|
3
3
|
import type { AdversarialCaseCategory } from "./AdversarialCaseCategory.ts";
|
|
4
4
|
import type { AdversarialCaseExpectation } from "./AdversarialCaseExpectation.ts";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// @generated by ts-rs; do not edit. Run `
|
|
1
|
+
// @generated by ts-rs; do not edit. Run `npm run contracts:generate`.
|
|
2
2
|
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
|
3
3
|
|
|
4
4
|
export type AdversarialCaseResultOutcome =
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// @generated by ts-rs; do not edit. Run `
|
|
1
|
+
// @generated by ts-rs; do not edit. Run `npm run contracts:generate`.
|
|
2
2
|
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
|
3
3
|
|
|
4
4
|
export type AdversarialCaseSource =
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// @generated by ts-rs; do not edit. Run `
|
|
1
|
+
// @generated by ts-rs; do not edit. Run `npm run contracts:generate`.
|
|
2
2
|
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
|
3
3
|
import type { AdversarialCase } from "./AdversarialCase.ts";
|
|
4
4
|
import type { AdversarialCaseResult } from "./AdversarialCaseResult.ts";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// @generated by ts-rs; do not edit. Run `
|
|
1
|
+
// @generated by ts-rs; do not edit. Run `npm run contracts:generate`.
|
|
2
2
|
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
|
3
3
|
|
|
4
4
|
export type AdversarialValidationStatus = "not-run" | "passed" | "failed";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// @generated by ts-rs; do not edit. Run `
|
|
1
|
+
// @generated by ts-rs; do not edit. Run `npm run contracts:generate`.
|
|
2
2
|
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
|
3
3
|
import type { BashListOperator } from "./BashListOperator.ts";
|
|
4
4
|
import type { BashPipeline } from "./BashPipeline.ts";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// @generated by ts-rs; do not edit. Run `
|
|
1
|
+
// @generated by ts-rs; do not edit. Run `npm run contracts:generate`.
|
|
2
2
|
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
|
3
3
|
import type { BashBlock } from "./BashBlock.ts";
|
|
4
4
|
import type { BashPathFacts } from "./BashPathFacts.ts";
|