@herbertgao/pi-extensions 2026.9.5 → 2026.9.7
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/README.md +5 -22
- package/THIRD_PARTY_NOTICES.md +0 -4
- package/node_modules/@herbertgao/sol-pi/docs/compatibility.md +1 -1
- package/node_modules/@herbertgao/sol-pi/package.json +1 -1
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/index.ts +0 -5
- package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/state.ts +3 -1
- package/node_modules/@narumitw/pi-btw/README.md +2 -0
- package/node_modules/@narumitw/pi-btw/dist/index.ts +284 -365
- package/node_modules/@narumitw/pi-btw/dist/index.ts.map +3 -3
- package/node_modules/@narumitw/pi-btw/package.json +52 -53
- package/node_modules/@narumitw/pi-btw/src/bring-to-main.ts +494 -547
- package/node_modules/@narumitw/pi-btw/src/btw.ts +814 -856
- package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +673 -674
- package/node_modules/@narumitw/pi-btw/src/keybindings.ts +228 -270
- package/node_modules/@narumitw/pi-btw/src/main-tree-picker.ts +309 -318
- package/node_modules/@narumitw/pi-btw/src/menu.ts +416 -454
- package/node_modules/@narumitw/pi-btw/src/settings.ts +203 -219
- package/node_modules/@narumitw/pi-btw/src/side-thread.ts +173 -201
- package/node_modules/@narumitw/pi-btw/src/text.ts +21 -23
- package/node_modules/@narumitw/pi-btw/src/transcript-markdown.ts +65 -0
- package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +611 -662
- package/node_modules/pi-lens/CHANGELOG.md +239 -0
- package/node_modules/pi-lens/config/dependency-cruiser-eager-allowlist.json +3 -0
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +30 -4
- package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +2 -0
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +26 -0
- package/node_modules/pi-lens/dist/clients/biome-client.js +1 -1
- package/node_modules/pi-lens/dist/clients/blocker-freshness.js +403 -35
- package/node_modules/pi-lens/dist/clients/bootstrap.js +6 -1
- package/node_modules/pi-lens/dist/clients/cascade-format.js +200 -4
- package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +10 -2
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +16 -1
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +12 -1
- package/node_modules/pi-lens/dist/clients/dispatch/ast-grep-catalog.js +65 -0
- package/node_modules/pi-lens/dist/clients/dispatch/auxiliary-lsp.js +28 -0
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +9 -2
- package/node_modules/pi-lens/dist/clients/dispatch/finding-policy.js +222 -0
- package/node_modules/pi-lens/dist/clients/dispatch/indent-detect.js +389 -13
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +175 -25
- package/node_modules/pi-lens/dist/clients/dispatch/rule-ignores.js +62 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +21 -41
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +6 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +7 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +2 -12
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +2 -21
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/types.js +4 -1
- package/node_modules/pi-lens/dist/clients/disposition-publish.js +1 -0
- package/node_modules/pi-lens/dist/clients/effective-config.js +1 -1
- package/node_modules/pi-lens/dist/clients/file-kinds.js +26 -1
- package/node_modules/pi-lens/dist/clients/file-role.js +21 -21
- package/node_modules/pi-lens/dist/clients/file-utils.js +156 -10
- package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +56 -9
- package/node_modules/pi-lens/dist/clients/format-service.js +39 -21
- package/node_modules/pi-lens/dist/clients/formatters.js +60 -13
- package/node_modules/pi-lens/dist/clients/generation-guard.js +2 -2
- package/node_modules/pi-lens/dist/clients/git-guard.js +11 -3
- package/node_modules/pi-lens/dist/clients/indent-retarget.js +78 -8
- package/node_modules/pi-lens/dist/clients/installer/index.js +333 -114
- package/node_modules/pi-lens/dist/clients/instance-reaper-state.js +7 -0
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +20 -10
- package/node_modules/pi-lens/dist/clients/language-profile.js +23 -1
- package/node_modules/pi-lens/dist/clients/language-registry.js +5 -1
- package/node_modules/pi-lens/dist/clients/latency-logger.js +4 -1
- package/node_modules/pi-lens/dist/clients/lens-engine.js +12 -3
- package/node_modules/pi-lens/dist/clients/lens-events.js +2 -1
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +79 -0
- package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +2 -1
- package/node_modules/pi-lens/dist/clients/lsp/client.js +25 -21
- package/node_modules/pi-lens/dist/clients/lsp/config.js +2 -2
- package/node_modules/pi-lens/dist/clients/lsp/index.js +7 -0
- package/node_modules/pi-lens/dist/clients/lsp/launch.js +16 -4
- package/node_modules/pi-lens/dist/clients/lsp/server.js +19 -2
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +2 -1
- package/node_modules/pi-lens/dist/clients/lsp-mutation.js +5 -3
- package/node_modules/pi-lens/dist/clients/map-with-concurrency.js +12 -8
- package/node_modules/pi-lens/dist/clients/mcp/session.js +36 -4
- package/node_modules/pi-lens/dist/clients/ndjson-logger.js +24 -7
- package/node_modules/pi-lens/dist/clients/observed-mutation.js +40 -2
- package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +23 -3
- package/node_modules/pi-lens/dist/clients/opengrep-client.js +110 -15
- package/node_modules/pi-lens/dist/clients/path-utils.js +123 -3
- package/node_modules/pi-lens/dist/clients/performance-report.js +5 -1
- package/node_modules/pi-lens/dist/clients/php-cs-fixer-config.js +1 -1
- package/node_modules/pi-lens/dist/clients/pipeline.js +74 -5
- package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +37 -5
- package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +145 -18
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/dead-code.js +4 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +59 -3
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +45 -2
- package/node_modules/pi-lens/dist/clients/read-guard.js +70 -11
- package/node_modules/pi-lens/dist/clients/resource-sampler.js +147 -9
- package/node_modules/pi-lens/dist/clients/ruff-client.js +1 -1
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +33 -5
- package/node_modules/pi-lens/dist/clients/runtime-context.js +6 -2
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +77 -7
- package/node_modules/pi-lens/dist/clients/runtime-session.js +21 -2
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +43 -12
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +330 -85
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +147 -17
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +258 -5
- package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +6 -0
- package/node_modules/pi-lens/dist/clients/session-event-guard.js +50 -5
- package/node_modules/pi-lens/dist/clients/sg-runner.js +23 -11
- package/node_modules/pi-lens/dist/clients/sgconfig.js +79 -2
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +6 -41
- package/node_modules/pi-lens/dist/clients/test-runner-delivery.js +43 -0
- package/node_modules/pi-lens/dist/clients/tool-agreement.js +423 -0
- package/node_modules/pi-lens/dist/clients/tool-config.js +50 -0
- package/node_modules/pi-lens/dist/clients/tool-cwd.js +47 -76
- package/node_modules/pi-lens/dist/clients/tool-policy.js +163 -7
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +120 -0
- package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +127 -189
- package/node_modules/pi-lens/dist/clients/widget-state.js +98 -0
- package/node_modules/pi-lens/dist/clients/word-index.js +5 -2
- package/node_modules/pi-lens/dist/clients/write-ordering-guard.js +7 -0
- package/node_modules/pi-lens/dist/index.js +27416 -24153
- package/node_modules/pi-lens/dist/mcp/server.js +5 -2
- package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +7 -1
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +168 -53
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +244 -72
- package/node_modules/pi-lens/docs/audit1.md +5 -5
- package/node_modules/pi-lens/docs/dependencies.md +11 -0
- package/node_modules/pi-lens/docs/dispositions.md +52 -0
- package/node_modules/pi-lens/docs/environment-variables.md +2 -2
- package/node_modules/pi-lens/docs/features.md +4 -4
- package/node_modules/pi-lens/docs/globalconfig.md +3 -1
- package/node_modules/pi-lens/docs/language-coverage.md +1 -0
- package/node_modules/pi-lens/docs/pi-lens-fixer.md +53 -94
- package/node_modules/pi-lens/docs/pi-lens-investigator.md +43 -38
- package/node_modules/pi-lens/docs/pi-lens-retro.md +97 -0
- package/node_modules/pi-lens/docs/pi-lens-reviewer.md +53 -66
- package/node_modules/pi-lens/docs/release-qa-baseline.md +22 -0
- package/node_modules/pi-lens/docs/settings.md +7 -4
- package/node_modules/pi-lens/docs/tree-sitter_rules_catalog.md +1 -1
- package/node_modules/pi-lens/docs/usage.md +2 -0
- package/node_modules/pi-lens/package.json +1 -1
- package/node_modules/pi-lens/rules/tree-sitter-queries/typescript/sql-injection.yml +24 -12
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +40 -0
- package/node_modules/pi-lens/skills/pi-lens-ast-grep/SKILL.md +15 -0
- package/node_modules/pi-lens/skills/pi-lens-lsp-navigation/SKILL.md +7 -0
- package/package.json +6 -17
- package/examples/pi-footer.json +0 -275
- package/node_modules/@czottmann/pi-automode/CHANGELOG.md +0 -70
- package/node_modules/@czottmann/pi-automode/LICENSE.md +0 -21
- package/node_modules/@czottmann/pi-automode/README.md +0 -215
- package/node_modules/@czottmann/pi-automode/docs/GLOSSARY.md +0 -39
- package/node_modules/@czottmann/pi-automode/docs/adr/ADR-001-permission-precedence-and-trust-boundaries.md +0 -46
- package/node_modules/@czottmann/pi-automode/docs/adr/ADR-002-global-config-in-extension-data-directory.md +0 -60
- package/node_modules/@czottmann/pi-automode/docs/adr/INDEX.md +0 -6
- package/node_modules/@czottmann/pi-automode/docs/automode-classifier-flow.md +0 -428
- package/node_modules/@czottmann/pi-automode/docs/configuration.md +0 -171
- package/node_modules/@czottmann/pi-automode/docs/defaults.md +0 -178
- package/node_modules/@czottmann/pi-automode/docs/diagnostics.md +0 -90
- package/node_modules/@czottmann/pi-automode/docs/observability-logging.md +0 -160
- package/node_modules/@czottmann/pi-automode/examples/automode.local.json +0 -44
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/bash.ts +0 -692
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/classifier.ts +0 -852
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/config.ts +0 -904
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/constants.ts +0 -228
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/extension.ts +0 -954
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/hard-deny.ts +0 -429
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/log.ts +0 -173
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/model-selector.ts +0 -113
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/model.ts +0 -13
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/paths.ts +0 -297
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/permissions.ts +0 -623
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/state.ts +0 -102
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/transcript.ts +0 -236
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/types.ts +0 -205
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/utils.ts +0 -54
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode.ts +0 -26
- package/node_modules/@czottmann/pi-automode/package.json +0 -61
- package/node_modules/@czottmann/pi-automode/skills/automode-diagnostics/SKILL.md +0 -63
- package/node_modules/@luxusai/pi-hindsight/CHANGELOG.md +0 -376
- package/node_modules/@luxusai/pi-hindsight/README.md +0 -92
- package/node_modules/@luxusai/pi-hindsight/docs/adr/001-memory-lifecycle-and-scope.md +0 -56
- package/node_modules/@luxusai/pi-hindsight/docs/adr/002-explicit-routing-strategy-seam.md +0 -169
- package/node_modules/@luxusai/pi-hindsight/docs/adr/003-tui-memory-mode-vocabulary.md +0 -107
- package/node_modules/@luxusai/pi-hindsight/docs/adr/004-lifeos-dual-bank-design.md +0 -89
- package/node_modules/@luxusai/pi-hindsight/docs/adr/005-domain-banks-and-agent-first-surface.md +0 -189
- package/node_modules/@luxusai/pi-hindsight/docs/assets/logos/pi-hindsight-logo-dark.webp +0 -0
- package/node_modules/@luxusai/pi-hindsight/docs/assets/logos/pi-hindsight-logo-dark@2x.webp +0 -0
- package/node_modules/@luxusai/pi-hindsight/docs/coding-memory-evaluation.md +0 -54
- package/node_modules/@luxusai/pi-hindsight/docs/compatibility.md +0 -75
- package/node_modules/@luxusai/pi-hindsight/docs/hindsight-core-functions.md +0 -300
- package/node_modules/@luxusai/pi-hindsight/docs/mission-and-mental-model-quality.md +0 -158
- package/node_modules/@luxusai/pi-hindsight/docs/next-opt-out-design.md +0 -164
- package/node_modules/@luxusai/pi-hindsight/docs/risky-memory-modes.md +0 -139
- package/node_modules/@luxusai/pi-hindsight/docs/starter-mental-model-suggestions.md +0 -74
- package/node_modules/@luxusai/pi-hindsight/docs/surface-reference.md +0 -261
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-operations.ts +0 -151
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-selection.ts +0 -18
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-settings-presenter.ts +0 -46
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-templates.ts +0 -383
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/banking.ts +0 -240
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/knowledge-page-seed.ts +0 -176
- package/node_modules/@luxusai/pi-hindsight/extensions/banks/retain-strategies.ts +0 -178
- package/node_modules/@luxusai/pi-hindsight/extensions/client/client-retry.ts +0 -41
- package/node_modules/@luxusai/pi-hindsight/extensions/client/client.ts +0 -386
- package/node_modules/@luxusai/pi-hindsight/extensions/client/fetch-compat.ts +0 -39
- package/node_modules/@luxusai/pi-hindsight/extensions/client/timeout.ts +0 -34
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-defaults.ts +0 -140
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-editing-model.ts +0 -61
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-editing-registry.ts +0 -925
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-field-paths.ts +0 -247
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-normalize.ts +0 -547
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config-writer.ts +0 -480
- package/node_modules/@luxusai/pi-hindsight/extensions/config/config.ts +0 -182
- package/node_modules/@luxusai/pi-hindsight/extensions/config/setup-gate.ts +0 -86
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-execute.ts +0 -1010
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-parse.ts +0 -175
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-plan.ts +0 -425
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-presentation.ts +0 -210
- package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-sessions.ts +0 -817
- package/node_modules/@luxusai/pi-hindsight/extensions/index.ts +0 -25
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/git-seed.ts +0 -319
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-recall.ts +0 -196
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-retain.ts +0 -189
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-runtime.ts +0 -65
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle.ts +0 -260
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/mental-models.ts +0 -244
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/observation-scopes.ts +0 -59
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall-cleanup.ts +0 -82
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall-visibility.ts +0 -45
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall.ts +0 -331
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-cursor.ts +0 -354
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-job-builder.ts +0 -66
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-receipts.ts +0 -132
- package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain.ts +0 -228
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-bank-template-operations.ts +0 -74
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-config-operations.ts +0 -16
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-control-operations.ts +0 -648
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-diagnostics-operations.ts +0 -105
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-identity.ts +0 -68
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-operation-service.ts +0 -71
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-operation-types.ts +0 -13
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-recall-operations.ts +0 -162
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-retain-operations.ts +0 -131
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-scope.ts +0 -104
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-session-operations.ts +0 -37
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/operation-catalog.ts +0 -893
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/reflect-presenter.ts +0 -35
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/scope-migrate.ts +0 -177
- package/node_modules/@luxusai/pi-hindsight/extensions/operations/tools.ts +0 -7
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/flush-presenter.ts +0 -21
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/jsonl-queue-store.ts +0 -112
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-delivery.ts +0 -111
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-lock.ts +0 -214
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-operations.ts +0 -70
- package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue.ts +0 -392
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/bank-template-presentation.ts +0 -45
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/commands.ts +0 -9
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/guided-setup.ts +0 -860
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/prefill-input.ts +0 -105
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-flow.ts +0 -189
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-server-probe.ts +0 -299
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-actions.ts +0 -201
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-facts.ts +0 -47
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-render.ts +0 -239
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-types.ts +0 -50
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui.ts +0 -259
- package/node_modules/@luxusai/pi-hindsight/extensions/tui/tool-presenters.ts +0 -77
- package/node_modules/@luxusai/pi-hindsight/extensions/types.ts +0 -534
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/diagnostics.ts +0 -319
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/messages.ts +0 -325
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/sanitize.ts +0 -42
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/session-memory-meta.ts +0 -244
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/session-operations.ts +0 -56
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/session.ts +0 -50
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/status-fields.ts +0 -167
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/status-health.ts +0 -207
- package/node_modules/@luxusai/pi-hindsight/extensions/utils/status.ts +0 -120
- package/node_modules/@luxusai/pi-hindsight/extensions/version.ts +0 -8
- package/node_modules/@luxusai/pi-hindsight/package.json +0 -118
- package/node_modules/@luxusai/pi-hindsight/skills/hindsight-memory-doctor/SKILL.md +0 -75
|
@@ -1,428 +0,0 @@
|
|
|
1
|
-
# Auto-mode classifier flow
|
|
2
|
-
|
|
3
|
-
This document describes how `pi-automode` decides whether an agent tool call can run. The classifier is only one part of the flow. Several checks happen before any model call, and some tool calls never reach the classifier at all.
|
|
4
|
-
|
|
5
|
-
## Short version
|
|
6
|
-
|
|
7
|
-
For each Pi `tool_call` event, the extension does this:
|
|
8
|
-
|
|
9
|
-
1. Load the effective auto-mode configuration for the current session.
|
|
10
|
-
2. If auto mode is disabled, ignore the call.
|
|
11
|
-
3. If the agent turn was cancelled, block the call.
|
|
12
|
-
4. Block a matching `permissions.deny` rule.
|
|
13
|
-
5. If a `permissions.ask` rule matches, ask the user.
|
|
14
|
-
6. If the user declines or no UI is available, block the call.
|
|
15
|
-
7. Mark an accepted ask call for required classifier review.
|
|
16
|
-
8. Run deterministic hard-deny checks.
|
|
17
|
-
9. If no accepted ask rule requires review, let the extension-owned `automode_inspect` tool run locally.
|
|
18
|
-
10. Run path-deny checks, including recursive search scopes and symlink aliases.
|
|
19
|
-
11. If an ask rule was accepted, skip all deterministic allow tiers.
|
|
20
|
-
12. Otherwise, apply the inside-working-directory, `permissions.allow`, and read-only tiers in that order.
|
|
21
|
-
13. Send every remaining action through a one-token conservative filter.
|
|
22
|
-
14. If the filter requests review, run structured classifier review.
|
|
23
|
-
15. Persist state and update the UI status and denial history.
|
|
24
|
-
|
|
25
|
-
The default posture is fail-closed. If model resolution, authentication, a classifier call, or response parsing fails, pi-automode blocks the action.
|
|
26
|
-
|
|
27
|
-
## Diagram
|
|
28
|
-
|
|
29
|
-
```mermaid
|
|
30
|
-
flowchart TD
|
|
31
|
-
A[Pi emits tool_call] --> B[Build effective config]
|
|
32
|
-
B --> C{Auto-mode enabled?}
|
|
33
|
-
C -- no --> Z[Let tool run]
|
|
34
|
-
C -- yes --> D{Agent turn cancelled?}
|
|
35
|
-
D -- yes --> X[Block: cancelled]
|
|
36
|
-
D -- no --> F{Matches permissions.deny?}
|
|
37
|
-
F -- yes --> F1[Block locally]
|
|
38
|
-
F -- no --> G{Matches permissions.ask?}
|
|
39
|
-
|
|
40
|
-
G -- yes --> H{UI available?}
|
|
41
|
-
H -- no --> H1[Block locally]
|
|
42
|
-
H -- yes --> I[Ask user]
|
|
43
|
-
I -- declined --> I1[Block locally]
|
|
44
|
-
I -- accepted --> J[Require classifier review]
|
|
45
|
-
G -- no --> J0[Continue normally]
|
|
46
|
-
|
|
47
|
-
J --> K{Deterministic hard-deny?}
|
|
48
|
-
J0 --> K
|
|
49
|
-
K -- yes --> K1[Block locally]
|
|
50
|
-
K -- no --> E{Extension-owned automode_inspect?}
|
|
51
|
-
E -- yes --> E2{Classifier required by ask?}
|
|
52
|
-
E2 -- no --> E1[Allow without state or log changes]
|
|
53
|
-
E2 -- yes --> N[Run one-token filter]
|
|
54
|
-
E -- no --> K2{Path denied or recursive scope unsafe?}
|
|
55
|
-
|
|
56
|
-
K2 -- yes --> K1
|
|
57
|
-
K2 -- no --> K3{Classifier required by ask?}
|
|
58
|
-
K3 -- yes --> N
|
|
59
|
-
K3 -- no --> K4{Inside-CWD allow tier?}
|
|
60
|
-
K4 -- yes, non-protected --> L1[Allow locally]
|
|
61
|
-
K4 -- no or protected --> K5{Matches permissions.allow?}
|
|
62
|
-
K5 -- yes, non-protected --> L1
|
|
63
|
-
K5 -- no or protected --> L{Read-only built-in fast path?}
|
|
64
|
-
L -- yes --> L1
|
|
65
|
-
L -- no --> N
|
|
66
|
-
|
|
67
|
-
N --> O{Exact safe token?}
|
|
68
|
-
O -- yes --> Q[Allow tool]
|
|
69
|
-
O -- malformed or error --> O1[Block: fail closed]
|
|
70
|
-
O -- review --> P[Run structured review]
|
|
71
|
-
P --> P1{Valid allow decision?}
|
|
72
|
-
P1 -- yes --> Q
|
|
73
|
-
P1 -- no or error --> R[Block with classifier reason]
|
|
74
|
-
|
|
75
|
-
X --> S[Persist state and update UI]
|
|
76
|
-
F1 --> S
|
|
77
|
-
H1 --> S
|
|
78
|
-
I1 --> S
|
|
79
|
-
K1 --> S
|
|
80
|
-
O1 --> S
|
|
81
|
-
R --> S
|
|
82
|
-
L1 --> T[Persist allow state and update UI]
|
|
83
|
-
Q --> T
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
## Configuration loading
|
|
87
|
-
|
|
88
|
-
Pi-automode loads global and inline configuration during extension initialization. It loads project configuration on `session_start`. `/automode reload` reloads the effective configuration.
|
|
89
|
-
|
|
90
|
-
The effective configuration combines these sources:
|
|
91
|
-
|
|
92
|
-
- `~/.pi/agent/extensions/pi-automode/config.json`
|
|
93
|
-
- `.pi/automode.local.json` for trusted projects
|
|
94
|
-
- `PI_AUTOMODE_SETTINGS_JSON`
|
|
95
|
-
- shared `.pi/automode.json` for trusted projects, but only for `permissions.deny` and `permissions.ask`
|
|
96
|
-
|
|
97
|
-
Before `session_start`, pi-automode loads only global and inline configuration. If `ctx.isProjectTrusted()` returns `true`, it reads project configuration during `session_start` and `/automode reload`.
|
|
98
|
-
|
|
99
|
-
For an untrusted project, pi-automode ignores both project files. `/automode config` reports each ignored file that exists.
|
|
100
|
-
|
|
101
|
-
Shared `.pi/automode.json` cannot change `autoMode` rules or add `permissions.allow`. A checked-in file must not reduce classifier coverage. If shared configuration contains `permissions.allow`, `/automode config` reports a diagnostic.
|
|
102
|
-
|
|
103
|
-
Deny and ask patterns use this source order: global, shared project, project-local, inline. Allow patterns use this source order: global, project-local, inline.
|
|
104
|
-
|
|
105
|
-
To disable pi-automode for the current project, set `autoMode.enabled` to `false` in `.pi/automode.local.json`:
|
|
106
|
-
|
|
107
|
-
```json
|
|
108
|
-
{
|
|
109
|
-
"autoMode": {
|
|
110
|
-
"enabled": false
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
This affects only the trusted project-local configuration. Shared project `.pi/automode.json` cannot disable auto mode.
|
|
116
|
-
|
|
117
|
-
List fields such as `allow`, `soft_deny`, `hard_deny`, `environment`, and `protectedPaths` support `$defaults`. Omitting `$defaults` replaces the built-ins for that section only. See [Defaults and rule-list behavior](defaults.md).
|
|
118
|
-
|
|
119
|
-
## Context captured before classification
|
|
120
|
-
|
|
121
|
-
On `before_agent_start`, the extension appends `AUTO_MODE_GUIDANCE` to the system prompt. This text states that auto mode is active. It also prohibits bypasses or weaker controls.
|
|
122
|
-
|
|
123
|
-
The same hook extracts context files from Pi's `systemPromptOptions.contextFiles`. The extracted text becomes `loadedContext`. Pi-automode formats each context file as follows:
|
|
124
|
-
|
|
125
|
-
```text
|
|
126
|
-
# path/to/file
|
|
127
|
-
<truncated content>
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
Pi-automode truncates the middle of each file to 4000 UTF-16 code units.
|
|
131
|
-
|
|
132
|
-
## Local checks before the classifier
|
|
133
|
-
|
|
134
|
-
### `permissions.deny`
|
|
135
|
-
|
|
136
|
-
Pi-automode checks `permissions.deny` first. A matching rule blocks immediately. Pi-automode does not call the classifier.
|
|
137
|
-
|
|
138
|
-
Example rule:
|
|
139
|
-
|
|
140
|
-
```json
|
|
141
|
-
"bash(git push --force*)"
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
Permission patterns apply to a Pi tool and its primary argument. `bash` uses `input.command`. `read`, `write`, `edit`, `find`, and `ls` use the normalized resolved `input.path`.
|
|
145
|
-
|
|
146
|
-
`grep` uses `input.pattern`. If the applicable argument is absent, the matcher uses the serialized input object.
|
|
147
|
-
|
|
148
|
-
The `*` wildcard matches zero or more characters, including newlines and path separators. Matching is case-insensitive and uses a bounded linear-time algorithm. A configured pattern can contain at most 4,096 UTF-16 code units. A primary argument can contain at most 1,048,576 UTF-16 code units. A longer argument conservatively matches a scoped deny or ask rule.
|
|
149
|
-
|
|
150
|
-
### `permissions.ask`
|
|
151
|
-
|
|
152
|
-
`permissions.ask` runs after `permissions.deny`.
|
|
153
|
-
|
|
154
|
-
If a rule matches without an available UI, pi-automode blocks the action. If a UI is available, pi-automode shows a confirmation dialog.
|
|
155
|
-
|
|
156
|
-
The dialog contains the matched rule and the action summary.
|
|
157
|
-
|
|
158
|
-
Approving that dialog does not run the tool directly. Deterministic denial checks continue first. After these checks pass, the classifier reviews the call. The call cannot use `allowInsideWorkingDirectory`, `permissions.allow`, or the read-only fast path.
|
|
159
|
-
|
|
160
|
-
### `permissions.allow`
|
|
161
|
-
|
|
162
|
-
`permissions.allow` is a deterministic allow tier. It uses the same patterns as `deny` and `ask`. Thus, it covers built-in, MCP, and extension tools:
|
|
163
|
-
|
|
164
|
-
```json
|
|
165
|
-
"permissions": { "allow": ["bash(git status*)", "example-extension-tool"] }
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
The matcher understands primary arguments for `bash`, the file tools, and `grep`. It uses the serialized input object for other tools.
|
|
169
|
-
|
|
170
|
-
Use a bare tool name for an MCP or extension tool. An argument pattern compares against the serialized input object.
|
|
171
|
-
|
|
172
|
-
A match skips only the classifier call. The tier cannot override permission denials, hard-deny checks, path denials, or protected-path controls. An accepted ask rule also disables this tier for the current call.
|
|
173
|
-
|
|
174
|
-
Pi-automode reads allow entries from global, trusted project-local, and inline configuration. It ignores allow entries in shared project configuration and reports a diagnostic.
|
|
175
|
-
|
|
176
|
-
A configured pattern can contain at most 4,096 UTF-16 code units. An input can contain at most 1,048,576 UTF-16 code units for allow matching. A longer input returns no match and continues to classifier review. Deny and ask matching uses the opposite overflow result so these rules fail closed.
|
|
177
|
-
|
|
178
|
-
The default list is empty. Thus, behavior does not change without explicit user configuration. Decision logs use `kind: permissions.allow`.
|
|
179
|
-
|
|
180
|
-
`/automode status` reports the rule count. `/automode config` shows the resolved patterns.
|
|
181
|
-
|
|
182
|
-
[ADR-001](adr/ADR-001-permission-precedence-and-trust-boundaries.md) records the precedence and trust-boundary rationale.
|
|
183
|
-
|
|
184
|
-
### Deterministic hard-deny checks
|
|
185
|
-
|
|
186
|
-
Some actions are too risky to leave to the classifier. Pi-automode blocks these actions before classifier review.
|
|
187
|
-
|
|
188
|
-
Current deterministic blocks include these actions:
|
|
189
|
-
|
|
190
|
-
- writes to shell profile files
|
|
191
|
-
- writes to `~/.ssh/authorized_keys`
|
|
192
|
-
- edits to auto-mode or Pi permission safety-control files
|
|
193
|
-
- weaker TLS or certificate verification
|
|
194
|
-
- persistence changes such as cron jobs, launch agents, and system service enablement
|
|
195
|
-
- dangerous recursive deletes of root, home, or system paths
|
|
196
|
-
- selected system or SSH permission mutations
|
|
197
|
-
|
|
198
|
-
The `bash` checks use the `unbash` abstract syntax tree. They inspect chains, pipelines, compound commands, substitutions, redirects, and literal shell-wrapper scripts.
|
|
199
|
-
|
|
200
|
-
Recursive-delete checks hard-deny `/`, the user home root, and top-level system roots. They exempt subpaths of the user home because these paths contain user data.
|
|
201
|
-
|
|
202
|
-
Some distributions store `HOME` under `/var`. Fedora Silverblue uses `/var/home/<user>`, for example. Pi-automode does not treat `rm -rf` on this home subtree as a system-path delete. It still blocks `rm -rf ~`.
|
|
203
|
-
|
|
204
|
-
### Read-only bypass and the path gate
|
|
205
|
-
|
|
206
|
-
Pi-automode allows read-only built-in tools after the prior checks and the `permissions.allow` tier. `classifyReadOnlyTools: true` sends them to the classifier instead.
|
|
207
|
-
|
|
208
|
-
The read-only tool set is:
|
|
209
|
-
|
|
210
|
-
```text
|
|
211
|
-
read, grep, find, ls
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
Pi-automode still allows reads to protected paths.
|
|
215
|
-
|
|
216
|
-
Two optional fields change the deterministic tier. `deniedPaths` blocks matching file-tool paths before classifier review or an allow tier.
|
|
217
|
-
|
|
218
|
-
`allowInsideWorkingDirectory: true` allows file access inside the working directory without classifier review. This access includes writes and edits. Pi-automode sends all out-of-tree file access to the classifier, including reads.
|
|
219
|
-
|
|
220
|
-
Protected in-tree writes and edits do not use the local allow tier. They still reach the classifier.
|
|
221
|
-
|
|
222
|
-
By default, both fields are off and `permissions.allow` is empty. Thus, every write and edit reaches the classifier.
|
|
223
|
-
|
|
224
|
-
## Protected paths
|
|
225
|
-
|
|
226
|
-
The protected-path configuration identifies safety-sensitive targets. Examples include `.git`, `.pi`, editor directories, shell profiles, package-manager files, and hook files.
|
|
227
|
-
|
|
228
|
-
By default, every write and edit reaches the classifier. Thus, no direct-write allow path can bypass classifier policy.
|
|
229
|
-
|
|
230
|
-
Two optional features add a direct-write path for non-protected targets. `allowInsideWorkingDirectory: true` allows non-protected in-tree writes. A matching `permissions.allow` pattern has the same result.
|
|
231
|
-
|
|
232
|
-
Both features keep protected targets on the classifier route. `deniedPaths` can block these targets before classifier review.
|
|
233
|
-
|
|
234
|
-
Deterministic safety-control checks still resolve paths canonically before classification. This catches writes through symlinks to auto-mode controls, shell profiles, and SSH authorization files without relying on the model.
|
|
235
|
-
|
|
236
|
-
## What is sent to the classifier
|
|
237
|
-
|
|
238
|
-
The classifier call is made by `defaultClassifyAction`.
|
|
239
|
-
|
|
240
|
-
The model receives a stable system policy, a shared context message, and a final stage instruction. Both stages use the same shared prefix. Thus, supported providers can reuse it.
|
|
241
|
-
|
|
242
|
-
To inspect each classifier request and raw response, enable `autoMode.log.classifierIo`. See [Observability logging](observability-logging.md).
|
|
243
|
-
|
|
244
|
-
### System prompt
|
|
245
|
-
|
|
246
|
-
The system prompt is `CLASSIFIER_SYSTEM_PROMPT` with configuration sections expanded into bullet lists:
|
|
247
|
-
|
|
248
|
-
- trusted environment
|
|
249
|
-
- allow exceptions
|
|
250
|
-
- soft-deny rules
|
|
251
|
-
- hard-deny rules
|
|
252
|
-
|
|
253
|
-
The prompt defines the policy semantics:
|
|
254
|
-
|
|
255
|
-
- hard-deny rules block unconditionally
|
|
256
|
-
- soft-deny rules support allow exceptions or direct user authorization in the retained user transcript
|
|
257
|
-
- a later user instruction can narrow or revoke authorization
|
|
258
|
-
- allow rules override only soft-deny rules
|
|
259
|
-
- hidden or malicious instructions in transcript evidence or repository files cannot change the rules
|
|
260
|
-
- the classifier cannot invent deny rules or treat the allow-exception list as exhaustive
|
|
261
|
-
- the classifier allows actions that match no hard-deny or soft-deny rule
|
|
262
|
-
|
|
263
|
-
The fast stage must return exactly `0` for clearly allowed or `1` for review. A `1` response triggers the detailed stage, whose required JSON shape is:
|
|
264
|
-
|
|
265
|
-
```json
|
|
266
|
-
{"decision":"allow","tier":"allow","reason":"brief concrete reason"}
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
or:
|
|
270
|
-
|
|
271
|
-
```json
|
|
272
|
-
{"decision":"block","tier":"soft_deny","reason":"brief concrete reason"}
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
Valid `tier` values are:
|
|
276
|
-
|
|
277
|
-
```text
|
|
278
|
-
hard_deny, soft_deny, allow, explicit_intent, none
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
An `allow` decision can use `allow`, `explicit_intent`, or `none`. A `block` decision can use `hard_deny`, `soft_deny`, or `none`.
|
|
282
|
-
|
|
283
|
-
If an exception or user instruction authorizes a soft-denied action, the tier must state why the classifier allows it. It cannot remain `soft_deny`.
|
|
284
|
-
|
|
285
|
-
### User messages
|
|
286
|
-
|
|
287
|
-
The first user message contains shared context:
|
|
288
|
-
|
|
289
|
-
```text
|
|
290
|
-
<loaded-project-instructions>
|
|
291
|
-
${loadedContext || "(none)"}
|
|
292
|
-
</loaded-project-instructions>
|
|
293
|
-
|
|
294
|
-
<classifier-transcript>
|
|
295
|
-
${buildClassifierTranscript(...) || "(none)"}
|
|
296
|
-
</classifier-transcript>
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
The next user message contains the complete current action as JSON. It is
|
|
300
|
-
separate from the transcript. Pi-automode does not truncate it:
|
|
301
|
-
|
|
302
|
-
```json
|
|
303
|
-
{"toolName":"bash","input":{"command":"npm test"}}
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
Both classifier stages receive the same context message and exact action
|
|
307
|
-
message. If the exact action cannot fit in the classifier model's context
|
|
308
|
-
window, auto mode blocks the call instead of removing action content.
|
|
309
|
-
|
|
310
|
-
Pi-automode builds the transcript from active Pi context entries. It includes only:
|
|
311
|
-
|
|
312
|
-
- user text
|
|
313
|
-
- assistant tool-call names and payloads
|
|
314
|
-
|
|
315
|
-
Pi-automode excludes assistant prose, hidden reasoning, and tool results. User evidence and tool-call evidence have separate approximate-token budgets. Both budgets default to 4000.
|
|
316
|
-
|
|
317
|
-
The selector keeps the first and latest user messages. It fills the remaining budget from the newest eligible entries. It renders retained evidence in chronological order. It also marks omitted or truncated evidence.
|
|
318
|
-
|
|
319
|
-
Transcript truncation does not change the dedicated current-action message.
|
|
320
|
-
|
|
321
|
-
## Classifier model resolution
|
|
322
|
-
|
|
323
|
-
Pi-automode selects the classifier model in this order:
|
|
324
|
-
|
|
325
|
-
1. `autoMode.classifierModel` from configuration
|
|
326
|
-
2. the current Pi session model.
|
|
327
|
-
|
|
328
|
-
`/automode model provider/model-id` and the interactive model picker save `autoMode.classifierModel` to `~/.pi/agent/extensions/pi-automode/config.json`. Project-local `.pi/automode.local.json` can still override that global choice.
|
|
329
|
-
|
|
330
|
-
`autoMode.classifierReasoningLevel` can request `low`, `medium`, `high`, `xhigh`, or `max` reasoning for both stages.
|
|
331
|
-
|
|
332
|
-
When the key is absent, classifier calls omit a reasoning preference. The server then selects its default. When the key is present, classifier calls use the normalized Pi AI path.
|
|
333
|
-
|
|
334
|
-
Pi AI clamps the request to the nearest supported level. Models without reasoning support resolve to `off`. They remain on the normalized path without a reasoning preference.
|
|
335
|
-
|
|
336
|
-
Reasoning does not increase the stage token limits. A high level can use all stage tokens before it produces valid visible output. Truncation fails closed.
|
|
337
|
-
|
|
338
|
-
The fast-stage limit is 512 tokens. The detailed-stage limit is 1200 tokens. `low` matches the reasoning effort of Codex Auto Review.
|
|
339
|
-
|
|
340
|
-
The extension asks Pi's model registry for API credentials. If the model cannot be found or credentials are unavailable, classification returns a blocking decision:
|
|
341
|
-
|
|
342
|
-
```text
|
|
343
|
-
No classifier model/API key available; auto mode fails closed.
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
Classifier calls use `ctx.signal`, a stable classifier-specific session ID, and `cacheRetention: "short"`. They do not set a temperature because some providers reject it. The calls use provider defaults instead. Providers without cache affinity ignore that option.
|
|
347
|
-
|
|
348
|
-
`autoMode.classifierTimeoutMs` limits each fast-stage and detailed-stage request. The default is 20000 ms.
|
|
349
|
-
|
|
350
|
-
If a request exceeds its budget, pi-automode aborts it and blocks the action. A stalled provider stream has the same result.
|
|
351
|
-
|
|
352
|
-
The fast stage requires one visible digit and uses `maxTokens: 512`. Reasoning models can use hidden tokens before they emit the digit.
|
|
353
|
-
|
|
354
|
-
Extra visible content fails parsing. Detailed review uses `maxTokens: 1200`. It can retry once after malformed or truncated output.
|
|
355
|
-
|
|
356
|
-
## Parsing the classifier result
|
|
357
|
-
|
|
358
|
-
The fast-stage parser requires `stopReason: "stop"`. It removes surrounding whitespace and accepts only `0` or `1`.
|
|
359
|
-
|
|
360
|
-
Empty responses, additional content, malformed output, and non-stop responses block immediately. Observability logs preserve the untrimmed model response.
|
|
361
|
-
|
|
362
|
-
The detailed parser accepts only the requested JSON object from a response with `stopReason: "stop"`. It requires `decision`, `tier`, and `reason`.
|
|
363
|
-
|
|
364
|
-
The parser rejects wrappers, extra fields, unknown tiers, and empty reasons. If the response shape changes, it fails closed.
|
|
365
|
-
|
|
366
|
-
A response with `stopReason: "length"` can cause one retry. The truncated response cannot authorize an action. Other non-stop responses block immediately.
|
|
367
|
-
|
|
368
|
-
If detailed parsing fails after its retry, pi-automode blocks the action with this reason:
|
|
369
|
-
|
|
370
|
-
```text
|
|
371
|
-
Classifier response was not valid decision JSON; auto mode fails closed.
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
If the model call throws or returns an error or aborted response, pi-automode blocks the action immediately. It uses a classifier failure message.
|
|
375
|
-
|
|
376
|
-
## State, UI, and denial history
|
|
377
|
-
|
|
378
|
-
Every checked action increments `checkedActions`.
|
|
379
|
-
|
|
380
|
-
Allowed actions store:
|
|
381
|
-
|
|
382
|
-
- `lastDecision: "allow"`
|
|
383
|
-
- `lastReason`
|
|
384
|
-
|
|
385
|
-
Blocked actions also increment `blockedActions` and add a denial record. Each denial record contains:
|
|
386
|
-
|
|
387
|
-
- timestamp
|
|
388
|
-
- tool name
|
|
389
|
-
- reason
|
|
390
|
-
- action summary
|
|
391
|
-
- denial kind
|
|
392
|
-
|
|
393
|
-
Recent denial history has a limit of 12 entries. Pi-automode persists state with `pi.appendEntry("pi-automode-state", state)`. Thus, state survives reloads and session restoration.
|
|
394
|
-
|
|
395
|
-
When UI is available, the extension updates the footer status and shows a warning notification for blocked actions.
|
|
396
|
-
|
|
397
|
-
## Agent inspection tool
|
|
398
|
-
|
|
399
|
-
`automode_inspect` exposes `status`, `config`, `defaults`, and `denials` views to the agent. The extension verifies the source of the registered tool before it applies the exemption.
|
|
400
|
-
|
|
401
|
-
A tool from another extension with the same name still uses normal enforcement. Every view is read-only. After local checks pass, the hook returns before classifier routing and state updates.
|
|
402
|
-
|
|
403
|
-
Pi sends tool output to the model. Therefore, the `status` and `denials` views omit denial reasons and action summaries.
|
|
404
|
-
|
|
405
|
-
The `config` view contains effective rule text. Do not store secrets in automode rules.
|
|
406
|
-
|
|
407
|
-
No state-changing command has a tool equivalent. The user must run `/automode on`, `/automode off`, `/automode reload`, `/automode reset`, and `/automode model` directly. See [Agent diagnostics](diagnostics.md) for the inspection contract, privacy limits, and diagnosis workflow.
|
|
408
|
-
|
|
409
|
-
## Command interactions
|
|
410
|
-
|
|
411
|
-
The classifier flow can be inspected or changed through slash commands:
|
|
412
|
-
|
|
413
|
-
```text
|
|
414
|
-
/automode status
|
|
415
|
-
/automode on
|
|
416
|
-
/automode off
|
|
417
|
-
/automode reload
|
|
418
|
-
/automode reset
|
|
419
|
-
/automode defaults
|
|
420
|
-
/automode config
|
|
421
|
-
/automode denials
|
|
422
|
-
/automode model
|
|
423
|
-
/automode model provider/model-id
|
|
424
|
-
```
|
|
425
|
-
|
|
426
|
-
`/auto-mode` is an alias.
|
|
427
|
-
|
|
428
|
-
`/automode off` disables the whole flow for the current session. `/automode on` re-enables it. `/automode model` saves the classifier model to `~/.pi/agent/extensions/pi-automode/config.json`.
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
# Configuration
|
|
2
|
-
|
|
3
|
-
The extension follows the documented Claude Code configuration model where Pi supports it.
|
|
4
|
-
|
|
5
|
-
It reads `autoMode` only from Pi-owned configuration sources:
|
|
6
|
-
|
|
7
|
-
- `~/.pi/agent/extensions/pi-automode/config.json`
|
|
8
|
-
- `.pi/automode.local.json` for trusted projects
|
|
9
|
-
- `PI_AUTOMODE_SETTINGS_JSON`
|
|
10
|
-
|
|
11
|
-
At startup, pi-automode moves a legacy `~/.pi/agent/automode.json` file to the new global path. If both files exist, it uses the new file and reports the conflict. If migration fails, it uses the legacy file for that session and reports the error.
|
|
12
|
-
|
|
13
|
-
It does not read project configuration until Pi trusts the project. For an untrusted project, it ignores `.pi/automode.local.json` and `.pi/automode.json`. `/automode config` reports each ignored file that exists.
|
|
14
|
-
|
|
15
|
-
Shared project `.pi/automode.json` cannot weaken auto mode. For a trusted project, it can add `permissions.deny` and `permissions.ask` rules.
|
|
16
|
-
|
|
17
|
-
The shared file cannot set `autoMode` or add `permissions.allow` rules. If the file contains `permissions.allow`, `/automode config` reports a diagnostic.
|
|
18
|
-
|
|
19
|
-
To disable pi-automode for the current project, create or edit `.pi/automode.local.json`:
|
|
20
|
-
|
|
21
|
-
```json
|
|
22
|
-
{
|
|
23
|
-
"autoMode": {
|
|
24
|
-
"enabled": false
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
This file is project-local. Pi reads it only after project trust. Do not commit this file. Shared project `.pi/automode.json` cannot disable auto mode.
|
|
30
|
-
|
|
31
|
-
Set a global default classifier model in `~/.pi/agent/extensions/pi-automode/config.json`. For a trusted project, override it in `.pi/automode.local.json`.
|
|
32
|
-
|
|
33
|
-
`classifierReasoningLevel` requests `low`, `medium`, `high`, `xhigh`, or `max` reasoning for both classifier stages. If the key is absent, pi-automode sends no reasoning preference. The server then selects the level.
|
|
34
|
-
|
|
35
|
-
Pi AI clamps an unsupported value to the nearest level that the selected model supports. A model without reasoning support resolves to `off`. `low` matches the reasoning effort of Codex Auto Review.
|
|
36
|
-
|
|
37
|
-
Higher levels can use all 512 or 1200 stage tokens before they produce visible output. In this case, the classifier fails closed. If truncation occurs before the required `0` or `1` digit, increase `fastClassifierMaxTokens`. The default is 512, and the minimum is 16.
|
|
38
|
-
|
|
39
|
-
`classifierTimeoutMs` limits each classifier request in milliseconds. The default is 20000, and the minimum is 1000. The fast and detailed stages have separate budgets.
|
|
40
|
-
|
|
41
|
-
If a request stalls or exceeds its budget, pi-automode aborts it. Then auto mode fails closed and blocks the action.
|
|
42
|
-
|
|
43
|
-
`allowInsideWorkingDirectory` adds a deterministic allow tier for the file tools. The default value is `false`. The file tools are `read`, `write`, `edit`, `grep`, `find`, and `ls`.
|
|
44
|
-
|
|
45
|
-
The value `allowInsideWorkingDirectory: true` allows access to paths inside the working directory without classifier review. Pi-automode sends access to outside paths to the classifier. This rule also applies to read calls.
|
|
46
|
-
|
|
47
|
-
This tier takes precedence over `classifyReadOnlyTools`. If both configuration fields are enabled, pi-automode still allows in-tree file access locally. `classifyReadOnlyTools: true` does not change this behavior.
|
|
48
|
-
|
|
49
|
-
Protected in-tree targets do not use this allow tier. Writes and edits to `.git/hooks`, `.pi` controls, shell profiles, and configuration files still reach the classifier.
|
|
50
|
-
|
|
51
|
-
`deniedPaths` is a list of path glob patterns. The default list is `[]`. A matching pattern blocks a file-tool call before classifier review or an allow tier.
|
|
52
|
-
|
|
53
|
-
Patterns support `~`, `$HOME`, and `${HOME}` expansion. The `*` wildcard matches all characters, including `/`. Thus, `**/id_rsa` matches a private key at any depth.
|
|
54
|
-
|
|
55
|
-
Each pattern can contain at most 4,096 UTF-16 code units. Pi-automode matches the typed path and its symlink-resolved form. It also resolves the fixed path prefix of each pattern. Thus, a symlink alias cannot bypass a denied target.
|
|
56
|
-
|
|
57
|
-
If a recursive `grep` or `find` scope can contain a denied path, pi-automode blocks the call. A broad pattern such as `*.env` blocks these tools for every directory scope.
|
|
58
|
-
|
|
59
|
-
A matching path blocks the call without classifier review or an override. The list applies only to file tools. The classifier governs `bash` path access. Both keys use the normal scalar and array precedence.
|
|
60
|
-
|
|
61
|
-
`allowInsideWorkingDirectory` uses scalar precedence: global, then project-local, then `PI_AUTOMODE_SETTINGS_JSON`. `deniedPaths` entries accumulate across these configuration sources.
|
|
62
|
-
|
|
63
|
-
Shared project `.pi/automode.json` cannot set either field. Omitting either field at a higher-precedence source does not clear a lower-source value.
|
|
64
|
-
|
|
65
|
-
Example:
|
|
66
|
-
|
|
67
|
-
```json
|
|
68
|
-
{
|
|
69
|
-
"autoMode": {
|
|
70
|
-
"classifierModel": "provider/model-id",
|
|
71
|
-
"classifierReasoningLevel": "low",
|
|
72
|
-
"classifyReadOnlyTools": false,
|
|
73
|
-
"fastClassifierMaxTokens": 512,
|
|
74
|
-
"classifierTimeoutMs": 20000,
|
|
75
|
-
"allowInsideWorkingDirectory": false,
|
|
76
|
-
"deniedPaths": [],
|
|
77
|
-
"maxUserTranscriptTokens": 4000,
|
|
78
|
-
"maxToolTranscriptTokens": 4000,
|
|
79
|
-
"environment": [
|
|
80
|
-
"$defaults",
|
|
81
|
-
"Source control: github.example.com/acme-corp and all repos under it",
|
|
82
|
-
"Trusted internal domains: *.corp.example.com, git.example.com",
|
|
83
|
-
"Trusted cloud buckets: s3://acme-dev-artifacts, gs://acme-ci-cache",
|
|
84
|
-
"Key internal services: staging deploy API at deploy.corp.example.com"
|
|
85
|
-
],
|
|
86
|
-
"allow": ["$defaults"],
|
|
87
|
-
"protectedPaths": ["$defaults"],
|
|
88
|
-
"soft_deny": ["$defaults"],
|
|
89
|
-
"hard_deny": [
|
|
90
|
-
"$defaults",
|
|
91
|
-
"Never send repository contents to third-party code-review APIs"
|
|
92
|
-
]
|
|
93
|
-
},
|
|
94
|
-
"permissions": {
|
|
95
|
-
"deny": ["bash(rm -rf *)"],
|
|
96
|
-
"ask": ["bash(git push *)"],
|
|
97
|
-
"allow": ["bash(git status*)", "example-extension-tool"]
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
`maxUserTranscriptTokens` and `maxToolTranscriptTokens` are approximate budgets for each category. Both default to 4000 and accept integers of at least 32.
|
|
103
|
-
|
|
104
|
-
Pi-automode does not support the former `maxTranscriptLines` field. Evidence selection now uses token budgets instead of line counts.
|
|
105
|
-
|
|
106
|
-
## Ask-user tools and explicit authorization
|
|
107
|
-
|
|
108
|
-
Classifier evidence includes normal user messages and assistant tool-call inputs. It excludes assistant prose and all tool results. This exclusion includes answers from ask-user tools such as `@vanillagreen/pi-questions`.
|
|
109
|
-
|
|
110
|
-
Selecting "Yes" in that tool helps the agent select its next action. Pi-automode does not treat the result as authorization to override a soft deny.
|
|
111
|
-
|
|
112
|
-
Send the authorization as a normal chat message. Then the agent can retry the action. Tool results remain excluded because they can contain untrusted or prompt-injected content.
|
|
113
|
-
|
|
114
|
-
## `$defaults`
|
|
115
|
-
|
|
116
|
-
See [Defaults and rule-list behavior](defaults.md) for built-in `environment`, `allow`, `protectedPaths`, `soft_deny`, and `hard_deny` entries. The document also explains replacement behavior after omission of `$defaults`.
|
|
117
|
-
|
|
118
|
-
## Observability logging
|
|
119
|
-
|
|
120
|
-
Auto mode can write a JSONL observability log for decisions and classifier usage. Persisted sessions use a sidecar next to the Pi session file. In-memory sessions use a global application directory. Logging is off by default.
|
|
121
|
-
|
|
122
|
-
```json
|
|
123
|
-
{
|
|
124
|
-
"autoMode": {
|
|
125
|
-
"log": {
|
|
126
|
-
"enabled": true,
|
|
127
|
-
"classifierIo": false
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
With logging enabled, persisted-session sidecars also contain ccusage-compatible entries for every classifier response. When `classifierIo` is off, `ccusage pi` still reports a separate `-pi-automode` session. In-memory logs use the same entry shape but live outside the normal Pi session tree.
|
|
134
|
-
|
|
135
|
-
See [Observability logging](observability-logging.md) for the log file location, entry schema, and the `classifierIo` privacy tradeoff. Run `/automode config` to see the resolved log file path.
|
|
136
|
-
|
|
137
|
-
## Permission patterns
|
|
138
|
-
|
|
139
|
-
Permission patterns use Pi tool names. Examples include `bash(...)`, `write(...)`, `edit(...)`, and `read(...)`. The parser accepts capitalized names such as `Bash(...)`. The documented form is lowercase because Pi tool names are lowercase.
|
|
140
|
-
|
|
141
|
-
`permissions.allow` is a deterministic allow tier. The default list is `[]`. A matching rule skips classifier review.
|
|
142
|
-
|
|
143
|
-
Use this tier for a narrow command such as `bash(git status*)`. You can also use it for a side-effect-free extension or MCP tool.
|
|
144
|
-
|
|
145
|
-
The matcher understands primary arguments for `bash`, the file tools, and `grep`. For file tools, it uses the resolved `input.path`. For `grep`, it uses `input.pattern`.
|
|
146
|
-
|
|
147
|
-
For `bash`, pi-automode parses `input.command` with `unbash`. Deny and ask rules inspect each executable command in the Bash syntax tree. This includes pipelines, logical chains, compound commands, substitutions, and literal scripts passed to `bash -c`, `sh -c`, or `eval`. The analysis also follows these literal shell scripts through transparent `command`, `exec`, and `env` dispatch.
|
|
148
|
-
|
|
149
|
-
The matcher normalizes whitespace between Bash tokens. It preserves whitespace and quoting inside each token. Thus, `bash(git push*)` matches `git push origin main`. Quoted operators do not create extra commands.
|
|
150
|
-
|
|
151
|
-
A Bash allow decision requires coverage for each executable command. A multi-command pattern must match the same AST structure and operators. This structure check also applies to one command inside a group, wrapper, control structure, or background statement. Separate single-command patterns only cover top-level foreground chains and plain pipelines. Other supported structure requires one matching structural pattern. A multi-command pattern must match the same number of commands in the same order. Each pattern command must match its corresponding input command. One wildcard cannot hide an additional command or a different operator.
|
|
152
|
-
|
|
153
|
-
A redirect requires explicit coverage in the allow pattern. The redirect operator, file descriptor, variable name, and target pattern must match. Here-documents and dynamic redirect targets continue to the classifier. Parser errors, dynamic command names, and dynamic wrapper scripts cannot use `permissions.allow`.
|
|
154
|
-
|
|
155
|
-
Control nodes with unrepresented semantic values cannot use `permissions.allow`. This includes loops, functions, coprocesses, case statements, test commands, and arithmetic commands. These scripts continue to the classifier.
|
|
156
|
-
|
|
157
|
-
Pi-automode does not execute shell expansions. It cannot resolve aliases, variables, generated scripts, or dynamic `eval` input. These calls continue to the classifier unless a deterministic rule blocks them.
|
|
158
|
-
|
|
159
|
-
For other tools, the matcher uses the serialized input object. Use a bare tool name for an MCP or extension tool. For example, `example-extension-tool` matches every call to that tool.
|
|
160
|
-
|
|
161
|
-
The providing extension or MCP server defines the Pi tool name. Pi-automode does not need a predefined list.
|
|
162
|
-
|
|
163
|
-
A match skips only the classifier call. It cannot skip `permissions.deny`, deterministic hard-deny checks, `deniedPaths`, or protected-path controls. An accepted `permissions.ask` rule also takes precedence. After confirmation, the call continues through deterministic checks and then reaches the classifier. It cannot use `permissions.allow`, the inside-working-directory tier, or the read-only fast path.
|
|
164
|
-
|
|
165
|
-
Pi-automode reads `permissions.allow` only from global configuration, trusted `.pi/automode.local.json`, and `PI_AUTOMODE_SETTINGS_JSON`. Shared `.pi/automode.json` cannot add allow rules.
|
|
166
|
-
|
|
167
|
-
A pattern can contain at most 4,096 UTF-16 code units. Bash analysis accepts at most 1,048,576 UTF-16 code units. A longer Bash input is blocked before parsing.
|
|
168
|
-
|
|
169
|
-
For other allow matching, an input can contain at most 1,048,576 UTF-16 code units. A longer input returns no match. Deny and ask patterns match the same oversized input so that they fail closed.
|
|
170
|
-
|
|
171
|
-
`write` and `edit` calls whose resolved target is a protected path are never covered by `permissions.allow`. This includes protected targets reached through symlink aliases.
|