@herbertgao/pi-extensions 2026.8.15 → 2026.9.1
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 +4 -1
- package/THIRD_PARTY_NOTICES.md +26 -0
- package/node_modules/@czottmann/pi-automode/CHANGELOG.md +13 -1
- package/node_modules/@czottmann/pi-automode/README.md +20 -0
- package/node_modules/@czottmann/pi-automode/docs/GLOSSARY.md +1 -1
- package/node_modules/@czottmann/pi-automode/docs/automode-classifier-flow.md +2 -1
- package/node_modules/@czottmann/pi-automode/docs/defaults.md +3 -2
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/classifier.ts +38 -2
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/constants.ts +5 -3
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/extension.ts +11 -3
- package/node_modules/@czottmann/pi-automode/package.json +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +20 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +46 -3
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/interaction.ts +55 -17
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/packets.ts +6 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/scroll.ts +5 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/result.ts +34 -30
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
- package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +2 -2
- package/node_modules/@narumitw/pi-btw/README.md +5 -1
- package/node_modules/@narumitw/pi-btw/dist/index.ts +143 -14
- package/node_modules/@narumitw/pi-btw/dist/index.ts.map +3 -3
- package/node_modules/@narumitw/pi-btw/package.json +4 -4
- package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +158 -7
- package/node_modules/@narumitw/pi-btw/src/text.ts +18 -0
- package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +5 -16
- package/node_modules/@narumitw/pi-caffeinate/LICENSE +21 -0
- package/node_modules/@narumitw/pi-caffeinate/README.md +224 -0
- package/node_modules/@narumitw/pi-caffeinate/dist/index.ts +1112 -0
- package/node_modules/@narumitw/pi-caffeinate/dist/index.ts.map +7 -0
- package/node_modules/@narumitw/pi-caffeinate/package.json +53 -0
- package/node_modules/@narumitw/pi-caffeinate/src/caffeinate.ts +811 -0
- package/node_modules/@narumitw/pi-caffeinate/src/dbus-inhibit.ts +153 -0
- package/node_modules/@narumitw/pi-caffeinate/src/index.ts +1 -0
- package/node_modules/@narumitw/pi-caffeinate/src/inhibitor-process.ts +43 -0
- package/node_modules/@narumitw/pi-caffeinate/src/inhibitors.ts +167 -0
- package/node_modules/@narumitw/pi-caffeinate/src/settings.ts +202 -0
- package/node_modules/@pi-plugins/fast-mode/README.md +5 -3
- package/node_modules/@pi-plugins/fast-mode/dist/index.d.mts.map +1 -1
- package/node_modules/@pi-plugins/fast-mode/dist/index.mjs +20 -55
- package/node_modules/@pi-plugins/fast-mode/dist/index.mjs.map +1 -1
- package/node_modules/@pi-plugins/fast-mode/package.json +1 -1
- package/node_modules/@tifan/pi-handoff/README.md +6 -3
- package/node_modules/@tifan/pi-handoff/package.json +1 -1
- package/node_modules/@tifan/pi-handoff/src/index.ts +8 -3
- package/node_modules/pi-lens/CHANGELOG.md +988 -0
- package/node_modules/pi-lens/README.md +3 -0
- package/node_modules/pi-lens/config/biome/core.jsonc +11 -2
- package/node_modules/pi-lens/config/dependency-cruiser-eager-allowlist.json +13 -1
- package/node_modules/pi-lens/dist/clients/actionable-warnings-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +927 -80
- package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +13 -4
- package/node_modules/pi-lens/dist/clients/ast-grep-client.js +123 -3
- package/node_modules/pi-lens/dist/clients/ast-grep-rule-manager.js +60 -5
- package/node_modules/pi-lens/dist/clients/ast-grep-tool-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +1 -3
- package/node_modules/pi-lens/dist/clients/biome-client.js +9 -2
- package/node_modules/pi-lens/dist/clients/blocker-freshness.js +14 -0
- package/node_modules/pi-lens/dist/clients/bootstrap.js +509 -73
- package/node_modules/pi-lens/dist/clients/bounded-cache.js +152 -12
- package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +59 -4
- package/node_modules/pi-lens/dist/clients/bundled-resource-health.js +113 -0
- package/node_modules/pi-lens/dist/clients/bus-events-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/cache/rule-cache.js +31 -4
- package/node_modules/pi-lens/dist/clients/cache-manager.js +105 -6
- package/node_modules/pi-lens/dist/clients/cache-observability.js +44 -18
- package/node_modules/pi-lens/dist/clients/cargo-manifest.js +422 -0
- package/node_modules/pi-lens/dist/clients/cascade-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +13 -3
- package/node_modules/pi-lens/dist/clients/complexity-client.js +16 -5
- package/node_modules/pi-lens/dist/clients/config-core/deny.js +221 -0
- package/node_modules/pi-lens/dist/clients/config-core/index.js +47 -0
- package/node_modules/pi-lens/dist/clients/config-core/merge.js +357 -0
- package/node_modules/pi-lens/dist/clients/config-core/normalize.js +340 -0
- package/node_modules/pi-lens/dist/clients/config-core/process-spec.js +248 -0
- package/node_modules/pi-lens/dist/clients/config-core/provenance.js +171 -0
- package/node_modules/pi-lens/dist/clients/config-core/records.js +218 -0
- package/node_modules/pi-lens/dist/clients/config-core/resolve.js +125 -0
- package/node_modules/pi-lens/dist/clients/config-core/safe-object.js +78 -0
- package/node_modules/pi-lens/dist/clients/config-core/schema.js +167 -0
- package/node_modules/pi-lens/dist/clients/config-diagnostic-codes.js +281 -0
- package/node_modules/pi-lens/dist/clients/config-locations.js +160 -0
- package/node_modules/pi-lens/dist/clients/config-resolve.js +789 -0
- package/node_modules/pi-lens/dist/clients/config-schema.js +197 -0
- package/node_modules/pi-lens/dist/clients/config-warn.js +407 -0
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +19 -14
- package/node_modules/pi-lens/dist/clients/dead-code-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/deadline-utils.js +178 -0
- package/node_modules/pi-lens/dist/clients/debug-handles.js +2 -2
- package/node_modules/pi-lens/dist/clients/debug-heap.js +3 -3
- package/node_modules/pi-lens/dist/clients/deferred-lsp-work.js +106 -0
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +113 -7
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +8 -19
- package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +12 -9
- package/node_modules/pi-lens/dist/clients/diagnostic-logger.js +14 -4
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +162 -18
- package/node_modules/pi-lens/dist/clients/dispatch/fact-store.js +97 -0
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +9 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +380 -26
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dart-analyze.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/fact-rules.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +1 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +13 -18
- package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/prisma-validate.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +7 -4
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rubocop.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +1 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +3 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +3 -4
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +194 -80
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +84 -15
- package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +0 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +0 -1
- package/node_modules/pi-lens/dist/clients/disposition-logger.js +3 -3
- package/node_modules/pi-lens/dist/clients/effective-config.js +403 -0
- package/node_modules/pi-lens/dist/clients/error-class.js +23 -0
- package/node_modules/pi-lens/dist/clients/event-loop-hold.js +274 -0
- package/node_modules/pi-lens/dist/clients/extension-log.js +2 -2
- package/node_modules/pi-lens/dist/clients/feature-hints.js +2 -1
- package/node_modules/pi-lens/dist/clients/file-time.js +6 -1
- package/node_modules/pi-lens/dist/clients/file-utils.js +112 -9
- package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +50 -13
- package/node_modules/pi-lens/dist/clients/format-service.js +6 -1
- package/node_modules/pi-lens/dist/clients/formatters.js +276 -102
- package/node_modules/pi-lens/dist/clients/freshness-cadence.js +17 -0
- package/node_modules/pi-lens/dist/clients/generated-artifacts.js +114 -19
- package/node_modules/pi-lens/dist/clients/generation-guard.js +4 -9
- package/node_modules/pi-lens/dist/clients/git-guard.js +1 -1
- package/node_modules/pi-lens/dist/clients/go-client.js +39 -0
- package/node_modules/pi-lens/dist/clients/gradle-ktfmt-style.js +252 -0
- package/node_modules/pi-lens/dist/clients/hashline-anchor.js +424 -0
- package/node_modules/pi-lens/dist/clients/hook-budgets.js +76 -0
- package/node_modules/pi-lens/dist/clients/host-edit-normalize.js +5 -2
- package/node_modules/pi-lens/dist/clients/host-ports.js +1 -1
- package/node_modules/pi-lens/dist/clients/installer/index.js +71 -52
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +104 -230
- package/node_modules/pi-lens/dist/clients/instance-registry.js +6 -3
- package/node_modules/pi-lens/dist/clients/language-registry.js +595 -0
- package/node_modules/pi-lens/dist/clients/latency-logger.js +160 -2
- package/node_modules/pi-lens/dist/clients/ledger-bounds.js +13 -0
- package/node_modules/pi-lens/dist/clients/lens-config.js +141 -30
- package/node_modules/pi-lens/dist/clients/lens-engine.js +30 -37
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +59 -6
- package/node_modules/pi-lens/dist/clients/log-cleanup.js +2 -2
- package/node_modules/pi-lens/dist/clients/lsp/aggregation.js +3 -1
- package/node_modules/pi-lens/dist/clients/lsp/client.js +168 -30
- package/node_modules/pi-lens/dist/clients/lsp/config.js +483 -158
- package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp/edits.js +15 -2
- package/node_modules/pi-lens/dist/clients/lsp/index.js +676 -71
- package/node_modules/pi-lens/dist/clients/lsp/language.js +18 -169
- package/node_modules/pi-lens/dist/clients/lsp/launch.js +2 -1
- package/node_modules/pi-lens/dist/clients/lsp/pending-aux-coverage.js +5 -16
- package/node_modules/pi-lens/dist/clients/lsp/server.js +284 -147
- package/node_modules/pi-lens/dist/clients/lsp/session-roots.js +116 -23
- package/node_modules/pi-lens/dist/clients/lsp/spawn-history.js +2 -7
- package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +9 -2
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +1 -1
- package/node_modules/pi-lens/dist/clients/lsp-mutation.js +163 -21
- package/node_modules/pi-lens/dist/clients/map-with-concurrency.js +36 -0
- package/node_modules/pi-lens/dist/clients/mcp/analyze.js +33 -4
- package/node_modules/pi-lens/dist/clients/mcp/session.js +5 -16
- package/node_modules/pi-lens/dist/clients/memory-sampler.js +8 -3
- package/node_modules/pi-lens/dist/clients/middle-man-analysis.js +2 -4
- package/node_modules/pi-lens/dist/clients/module-report.js +20 -45
- package/node_modules/pi-lens/dist/clients/mutating-tool.js +651 -0
- package/node_modules/pi-lens/dist/clients/mutation-attribution.js +368 -0
- package/node_modules/pi-lens/dist/clients/mutation-bridge.js +240 -0
- package/node_modules/pi-lens/dist/clients/ndjson-logger.js +247 -20
- package/node_modules/pi-lens/dist/clients/observed-mutation-sources.js +101 -0
- package/node_modules/pi-lens/dist/clients/observed-mutation.js +1215 -0
- package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +68 -22
- package/node_modules/pi-lens/dist/clients/opengrep-config.js +4 -0
- package/node_modules/pi-lens/dist/clients/package-manager.js +195 -26
- package/node_modules/pi-lens/dist/clients/partial-edit-apply.js +359 -80
- package/node_modules/pi-lens/dist/clients/path-attribution-telemetry.js +23 -7
- package/node_modules/pi-lens/dist/clients/path-keyed-map.js +21 -2
- package/node_modules/pi-lens/dist/clients/path-utils.js +428 -13
- package/node_modules/pi-lens/dist/clients/persist-debounce.js +8 -1
- package/node_modules/pi-lens/dist/clients/php-cs-fixer-config.js +114 -0
- package/node_modules/pi-lens/dist/clients/pipeline.js +77 -16
- package/node_modules/pi-lens/dist/clients/probe-home-state.js +228 -0
- package/node_modules/pi-lens/dist/clients/process-bridge.js +66 -0
- package/node_modules/pi-lens/dist/clients/process-snapshot.js +68 -0
- package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +4 -3
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +27 -3
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +51 -20
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +393 -122
- package/node_modules/pi-lens/dist/clients/project-snapshot.js +52 -24
- package/node_modules/pi-lens/dist/clients/python-environment.js +217 -0
- package/node_modules/pi-lens/dist/clients/python-provenance.js +639 -0
- package/node_modules/pi-lens/dist/clients/quiet-window.js +6 -1
- package/node_modules/pi-lens/dist/clients/read-bridge.js +13 -21
- package/node_modules/pi-lens/dist/clients/read-expansion.js +9 -46
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +15 -4
- package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +364 -212
- package/node_modules/pi-lens/dist/clients/read-guard.js +21 -0
- package/node_modules/pi-lens/dist/clients/resource-sampler.js +195 -96
- package/node_modules/pi-lens/dist/clients/review-graph/builder.js +152 -109
- package/node_modules/pi-lens/dist/clients/review-graph/service.js +55 -3
- package/node_modules/pi-lens/dist/clients/review-graph/shared-extraction-ir.js +7 -15
- package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +10 -74
- package/node_modules/pi-lens/dist/clients/review-graph-logger.js +9 -3
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +18 -2
- package/node_modules/pi-lens/dist/clients/runtime-context.js +49 -16
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +25 -6
- package/node_modules/pi-lens/dist/clients/runtime-session.js +139 -22
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +168 -35
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +797 -243
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +1028 -53
- package/node_modules/pi-lens/dist/clients/rust-client.js +31 -0
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +33 -10
- package/node_modules/pi-lens/dist/clients/sanitize.js +7 -1
- package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +1 -3
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +3 -0
- package/node_modules/pi-lens/dist/clients/session-lifecycle.js +1 -1
- package/node_modules/pi-lens/dist/clients/session-start-observability.js +79 -0
- package/node_modules/pi-lens/dist/clients/sessionstart-logger.js +12 -3
- package/node_modules/pi-lens/dist/clients/sgconfig.js +6 -1
- package/node_modules/pi-lens/dist/clients/skills-resolver.js +105 -0
- package/node_modules/pi-lens/dist/clients/smells-rollup.js +2 -2
- package/node_modules/pi-lens/dist/clients/string-utils.js +13 -0
- package/node_modules/pi-lens/dist/clients/subagent-mode.js +17 -4
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +176 -39
- package/node_modules/pi-lens/dist/clients/test-runner-delivery.js +239 -0
- package/node_modules/pi-lens/dist/clients/tool-definition.js +41 -1
- package/node_modules/pi-lens/dist/clients/tool-policy.js +91 -21
- package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +40 -40
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +86 -48
- package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +81 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +51 -46
- package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +28 -0
- package/node_modules/pi-lens/dist/clients/typos-config.js +5 -0
- package/node_modules/pi-lens/dist/clients/user-notify.js +6 -2
- package/node_modules/pi-lens/dist/clients/widget-state.js +191 -26
- package/node_modules/pi-lens/dist/clients/word-index-logger.js +2 -2
- package/node_modules/pi-lens/dist/clients/word-index-store.js +20 -5
- package/node_modules/pi-lens/dist/clients/word-index.js +243 -31
- package/node_modules/pi-lens/dist/clients/workspace-topology.js +8 -1
- package/node_modules/pi-lens/dist/clients/zizmor-config.js +3 -0
- package/node_modules/pi-lens/dist/index.js +64335 -54300
- package/node_modules/pi-lens/dist/mcp/analyze-cli.js +3 -1
- package/node_modules/pi-lens/dist/mcp/server.js +127 -5
- package/node_modules/pi-lens/dist/scripts/lib/process-scan.mjs +583 -0
- package/node_modules/pi-lens/dist/scripts/lib/skills-predicate.mjs +129 -0
- package/node_modules/pi-lens/dist/tools/effective-config.js +89 -0
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +95 -24
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +67 -80
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +37 -16
- package/node_modules/pi-lens/dist/tools/shared.js +0 -1
- package/node_modules/pi-lens/docs/agent-guide.md +64 -1
- package/node_modules/pi-lens/docs/configuration.md +222 -0
- package/node_modules/pi-lens/docs/dependencies.md +3 -3
- package/node_modules/pi-lens/docs/features.md +44 -5
- package/node_modules/pi-lens/docs/language-coverage.md +2 -2
- package/node_modules/pi-lens/docs/pi-lens-fixer.md +25 -0
- package/node_modules/pi-lens/docs/pi-lens-investigator.md +25 -0
- package/node_modules/pi-lens/docs/pi-lens-reviewer.md +27 -0
- package/node_modules/pi-lens/docs/pi-lens-subagent.md +38 -0
- package/node_modules/pi-lens/docs/pi-lens-warden.md +55 -0
- package/node_modules/pi-lens/docs/public-api-stability.md +359 -0
- package/node_modules/pi-lens/docs/release-qa-baseline.md +182 -0
- package/node_modules/pi-lens/docs/subagent-compat.md +110 -30
- package/node_modules/pi-lens/docs/tree-sitter_rules_catalog.md +2 -2
- package/node_modules/pi-lens/package.json +15 -23
- package/node_modules/pi-lens/rules/tree-sitter-queries/python/python-cross-language-method.yml +3 -3
- package/node_modules/pi-lens/rules/tree-sitter-queries/python/python-hallucinated-import.yml +2 -2
- package/node_modules/pi-lens/rules/tree-sitter-queries/python/python-sql-injection.yml +12 -2
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +192 -1
- package/node_modules/pi-lens/scripts/install-selftest.mjs +58 -2
- package/node_modules/pi-lens/scripts/lib/skills-predicate.mjs +129 -0
- package/node_modules/pi-lens/scripts/rpc-load-check.mjs +3 -1
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +27 -0
- package/node_modules/pi-mcp-adapter/README.md +13 -13
- package/node_modules/pi-mcp-adapter/commands.ts +58 -21
- package/node_modules/pi-mcp-adapter/config.ts +18 -4
- package/node_modules/pi-mcp-adapter/direct-tools.ts +26 -6
- package/node_modules/pi-mcp-adapter/dist/config.d.ts +4 -0
- package/node_modules/pi-mcp-adapter/dist/config.js +13 -4
- package/node_modules/pi-mcp-adapter/dist/config.js.map +1 -1
- package/node_modules/pi-mcp-adapter/dist/types.d.ts +11 -3
- package/node_modules/pi-mcp-adapter/dist/types.js.map +1 -1
- package/node_modules/pi-mcp-adapter/error-signal.ts +15 -4
- package/node_modules/pi-mcp-adapter/errors.ts +141 -0
- package/node_modules/pi-mcp-adapter/host-html-template.ts +58 -5
- package/node_modules/pi-mcp-adapter/index.ts +2 -3
- package/node_modules/pi-mcp-adapter/init.ts +5 -0
- package/node_modules/pi-mcp-adapter/mcp-panel.ts +30 -9
- package/node_modules/pi-mcp-adapter/mcp-setup-panel.ts +66 -28
- package/node_modules/pi-mcp-adapter/mcp-status.ts +2 -0
- package/node_modules/pi-mcp-adapter/package.json +2 -1
- package/node_modules/pi-mcp-adapter/proxy-modes.ts +66 -13
- package/node_modules/pi-mcp-adapter/sandbox-proxy-template.ts +217 -0
- package/node_modules/pi-mcp-adapter/server-manager.ts +337 -6
- package/node_modules/pi-mcp-adapter/skills/mcp-scripting/SKILL.md +1 -0
- package/node_modules/pi-mcp-adapter/types.ts +18 -3
- package/node_modules/pi-mcp-adapter/ui-resource-handler.ts +18 -2
- package/node_modules/pi-mcp-adapter/ui-server.ts +179 -54
- package/node_modules/pi-mcp-adapter/ui-session.ts +28 -8
- package/node_modules/pi-web-access/CHANGELOG.md +28 -0
- package/node_modules/pi-web-access/README.md +62 -15
- package/node_modules/pi-web-access/curator-page.ts +3 -1
- package/node_modules/pi-web-access/curator-server.ts +5 -1
- package/node_modules/pi-web-access/gemini-search.ts +8 -4
- package/node_modules/pi-web-access/github-extract.ts +242 -1
- package/node_modules/pi-web-access/index.ts +118 -64
- package/node_modules/pi-web-access/mistral-search.ts +281 -0
- package/node_modules/pi-web-access/package.json +2 -2
- package/node_modules/pi-web-access/perplexity.ts +14 -1
- package/node_modules/pi-web-access/utils.ts +23 -6
- package/node_modules/pi-web-access/xai-search.ts +96 -33
- package/package.json +15 -11
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import type { Message, MessageBus } from "dbus-native";
|
|
2
|
+
|
|
3
|
+
export const SCREENSAVER_BUS_NAME = "org.freedesktop.ScreenSaver";
|
|
4
|
+
export const SCREENSAVER_INTERFACE = "org.freedesktop.ScreenSaver";
|
|
5
|
+
export const INHIBIT_REASON = "Pi agent is running";
|
|
6
|
+
|
|
7
|
+
const INHIBIT_APPLICATION_NAME = "pi-caffeinate";
|
|
8
|
+
const SCREENSAVER_OBJECT_PATHS = ["/org/freedesktop/ScreenSaver", "/ScreenSaver"];
|
|
9
|
+
const DBUS_CALL_TIMEOUT_MS = 2_000;
|
|
10
|
+
|
|
11
|
+
type DbusFailureHandler = (error: Error) => void;
|
|
12
|
+
|
|
13
|
+
export interface DbusScreenSaverClient {
|
|
14
|
+
setFailureHandler(handler: DbusFailureHandler | undefined): void;
|
|
15
|
+
inhibit(reason: string, signal?: AbortSignal): Promise<void>;
|
|
16
|
+
uninhibit(): Promise<void>;
|
|
17
|
+
close(): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type DbusScreenSaverFactory = () => Promise<DbusScreenSaverClient>;
|
|
21
|
+
|
|
22
|
+
export async function defaultDbusScreenSaverFactory(): Promise<DbusScreenSaverClient> {
|
|
23
|
+
const { sessionBus } = await import("dbus-native");
|
|
24
|
+
return new NativeScreenSaverClient(sessionBus());
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
class NativeScreenSaverClient implements DbusScreenSaverClient {
|
|
28
|
+
private cookie?: number;
|
|
29
|
+
private objectPath?: string;
|
|
30
|
+
private failureHandler?: DbusFailureHandler;
|
|
31
|
+
private pendingFailure?: Error;
|
|
32
|
+
private lastConnectionError?: Error;
|
|
33
|
+
private closing = false;
|
|
34
|
+
|
|
35
|
+
private readonly handleConnectionError = (error: unknown) => {
|
|
36
|
+
this.lastConnectionError = toError(error, "D-Bus session connection failed");
|
|
37
|
+
if (this.cookie !== undefined) this.reportFailure(this.lastConnectionError);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
private readonly handleConnectionClose = (error?: unknown) => {
|
|
41
|
+
if (this.closing || this.cookie === undefined) return;
|
|
42
|
+
this.reportFailure(
|
|
43
|
+
toError(error, this.lastConnectionError?.message ?? "D-Bus session connection closed"),
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
constructor(private readonly bus: MessageBus) {
|
|
48
|
+
this.bus.connection.on("error", this.handleConnectionError);
|
|
49
|
+
this.bus.connection.on("close", this.handleConnectionClose);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
setFailureHandler(handler: DbusFailureHandler | undefined): void {
|
|
53
|
+
this.failureHandler = handler;
|
|
54
|
+
if (!handler || !this.pendingFailure) return;
|
|
55
|
+
const failure = this.pendingFailure;
|
|
56
|
+
this.pendingFailure = undefined;
|
|
57
|
+
handler(failure);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async inhibit(reason: string, signal?: AbortSignal): Promise<void> {
|
|
61
|
+
let lastError: unknown;
|
|
62
|
+
for (const objectPath of SCREENSAVER_OBJECT_PATHS) {
|
|
63
|
+
if (signal?.aborted) throw abortReason(signal);
|
|
64
|
+
try {
|
|
65
|
+
this.cookie = await invoke<number>(
|
|
66
|
+
this.bus,
|
|
67
|
+
{
|
|
68
|
+
destination: SCREENSAVER_BUS_NAME,
|
|
69
|
+
path: objectPath,
|
|
70
|
+
interface: SCREENSAVER_INTERFACE,
|
|
71
|
+
member: "Inhibit",
|
|
72
|
+
signature: "ss",
|
|
73
|
+
body: [INHIBIT_APPLICATION_NAME, reason],
|
|
74
|
+
},
|
|
75
|
+
signal,
|
|
76
|
+
);
|
|
77
|
+
this.objectPath = objectPath;
|
|
78
|
+
return;
|
|
79
|
+
} catch (error) {
|
|
80
|
+
if (signal?.aborted) throw abortReason(signal);
|
|
81
|
+
lastError = error;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
throw new Error(`D-Bus idle inhibit failed: ${formatError(lastError)}`, {
|
|
85
|
+
cause: lastError,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async uninhibit(): Promise<void> {
|
|
90
|
+
if (this.cookie === undefined || !this.objectPath) return;
|
|
91
|
+
const cookie = this.cookie;
|
|
92
|
+
this.cookie = undefined;
|
|
93
|
+
const objectPath = this.objectPath;
|
|
94
|
+
this.objectPath = undefined;
|
|
95
|
+
await invoke<void>(this.bus, {
|
|
96
|
+
destination: SCREENSAVER_BUS_NAME,
|
|
97
|
+
path: objectPath,
|
|
98
|
+
interface: SCREENSAVER_INTERFACE,
|
|
99
|
+
member: "UnInhibit",
|
|
100
|
+
signature: "u",
|
|
101
|
+
body: [cookie],
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async close(): Promise<void> {
|
|
106
|
+
this.closing = true;
|
|
107
|
+
this.cookie = undefined;
|
|
108
|
+
this.objectPath = undefined;
|
|
109
|
+
this.failureHandler = undefined;
|
|
110
|
+
try {
|
|
111
|
+
await this.bus.close();
|
|
112
|
+
} finally {
|
|
113
|
+
this.bus.connection.off("error", this.handleConnectionError);
|
|
114
|
+
this.bus.connection.off("close", this.handleConnectionClose);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private reportFailure(error: Error): void {
|
|
119
|
+
if (this.cookie === undefined) return;
|
|
120
|
+
this.cookie = undefined;
|
|
121
|
+
this.objectPath = undefined;
|
|
122
|
+
if (this.failureHandler) this.failureHandler(error);
|
|
123
|
+
else this.pendingFailure = error;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function invoke<TResult>(
|
|
128
|
+
bus: MessageBus,
|
|
129
|
+
message: Message,
|
|
130
|
+
signal?: AbortSignal,
|
|
131
|
+
): Promise<TResult> {
|
|
132
|
+
return new Promise<TResult>((resolve, reject) => {
|
|
133
|
+
bus.invoke(message, { signal, timeout: DBUS_CALL_TIMEOUT_MS }, (error, ...values) => {
|
|
134
|
+
if (error) reject(error);
|
|
135
|
+
else resolve(values[0] as TResult);
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function abortReason(signal: AbortSignal): unknown {
|
|
141
|
+
return signal.reason ?? new DOMException("D-Bus idle inhibit cancelled", "AbortError");
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function toError(error: unknown, fallback: string): Error {
|
|
145
|
+
return error instanceof Error ? error : new Error(fallback);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function formatError(error: unknown) {
|
|
149
|
+
if (error instanceof Error) {
|
|
150
|
+
return error.name === "Error" ? error.message : `${error.name}: ${error.message}`;
|
|
151
|
+
}
|
|
152
|
+
return String(error);
|
|
153
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./caffeinate.js";
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type ChildProcess, spawn } from "node:child_process";
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
import type { InhibitorCommand } from "./inhibitors.js";
|
|
4
|
+
|
|
5
|
+
export function startInhibitorProcess(
|
|
6
|
+
command: InhibitorCommand,
|
|
7
|
+
onError: (error: Error) => void,
|
|
8
|
+
onUnexpectedExit: (description: string) => void,
|
|
9
|
+
): ChildProcess {
|
|
10
|
+
const child = spawn(command.command, command.args, {
|
|
11
|
+
detached: false,
|
|
12
|
+
stdio: [command.releaseOnStdinClose ? "pipe" : "ignore", "pipe", "pipe"],
|
|
13
|
+
});
|
|
14
|
+
child.once("error", onError);
|
|
15
|
+
child.once("exit", (code, signal) => onUnexpectedExit(formatExit(code, signal)));
|
|
16
|
+
return child;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function stopInhibitorProcess(child: ChildProcess, command: InhibitorCommand | undefined) {
|
|
20
|
+
child.removeAllListeners("exit");
|
|
21
|
+
child.removeAllListeners("error");
|
|
22
|
+
if (child.killed) return;
|
|
23
|
+
|
|
24
|
+
if (command?.releaseOnStdinClose && child.stdin && !child.stdin.destroyed) {
|
|
25
|
+
child.stdin.end();
|
|
26
|
+
if (child.exitCode === null && child.signalCode === null) {
|
|
27
|
+
const killTimer = setTimeout(() => {
|
|
28
|
+
if (child.exitCode === null && child.signalCode === null && !child.killed) child.kill();
|
|
29
|
+
}, 2000);
|
|
30
|
+
killTimer.unref();
|
|
31
|
+
child.once("exit", () => clearTimeout(killTimer));
|
|
32
|
+
}
|
|
33
|
+
} else if (process.platform === "win32") {
|
|
34
|
+
child.kill();
|
|
35
|
+
} else {
|
|
36
|
+
child.kill("SIGTERM");
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function formatExit(code: number | null, signal: NodeJS.Signals | null) {
|
|
41
|
+
if (signal) return `signal ${signal}`;
|
|
42
|
+
return `code ${code ?? "unknown"}`;
|
|
43
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import type { CaffeinateMode } from "./settings.js";
|
|
5
|
+
|
|
6
|
+
export interface InhibitorCommand {
|
|
7
|
+
command: string;
|
|
8
|
+
args: string[];
|
|
9
|
+
description: string;
|
|
10
|
+
releaseOnStdinClose?: boolean;
|
|
11
|
+
custom?: boolean;
|
|
12
|
+
/** Display mode also needs D-Bus because logind idle inhibition misses some compositors. */
|
|
13
|
+
addDbusIdleInhibit?: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function getInhibitorCommand(mode: CaffeinateMode): InhibitorCommand | undefined {
|
|
17
|
+
const customCommand = process.env.PI_CAFFEINATE_COMMAND?.trim();
|
|
18
|
+
if (customCommand) {
|
|
19
|
+
const [command, ...args] = splitCommand(customCommand);
|
|
20
|
+
if (command) return { command, args, description: `custom command (${command})`, custom: true };
|
|
21
|
+
}
|
|
22
|
+
if (process.platform === "darwin") {
|
|
23
|
+
return parentBoundUnixCommand(
|
|
24
|
+
"caffeinate",
|
|
25
|
+
macCaffeinateArgs(mode),
|
|
26
|
+
caffeinateDescription(mode),
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
if (process.platform === "linux") {
|
|
30
|
+
if (isWsl() && commandExists("powershell.exe")) {
|
|
31
|
+
return windowsPowerInhibitorCommand("powershell.exe", mode);
|
|
32
|
+
}
|
|
33
|
+
if (commandExists("systemd-inhibit")) {
|
|
34
|
+
const what = mode === "display" ? "idle:sleep" : "sleep";
|
|
35
|
+
return parentBoundUnixCommand(
|
|
36
|
+
"systemd-inhibit",
|
|
37
|
+
[
|
|
38
|
+
`--what=${what}`,
|
|
39
|
+
"--who=pi-caffeinate",
|
|
40
|
+
"--why=Pi agent is running",
|
|
41
|
+
"--mode=block",
|
|
42
|
+
"sleep",
|
|
43
|
+
"infinity",
|
|
44
|
+
],
|
|
45
|
+
`systemd-inhibit (${formatMode(mode)})`,
|
|
46
|
+
mode === "display",
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
if (commandExists("caffeinate")) {
|
|
50
|
+
return parentBoundUnixCommand(
|
|
51
|
+
"caffeinate",
|
|
52
|
+
macCaffeinateArgs(mode),
|
|
53
|
+
caffeinateDescription(mode),
|
|
54
|
+
mode === "display",
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (process.platform === "win32") return windowsPowerInhibitorCommand("powershell.exe", mode);
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function macCaffeinateArgs(mode: CaffeinateMode) {
|
|
63
|
+
return mode === "sleep" ? ["-ims"] : ["-dimsu"];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function caffeinateDescription(mode: CaffeinateMode) {
|
|
67
|
+
return `caffeinate (${formatMode(mode)})`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function parentBoundUnixCommand(
|
|
71
|
+
command: string,
|
|
72
|
+
args: string[],
|
|
73
|
+
description: string,
|
|
74
|
+
addDbusIdleInhibit = false,
|
|
75
|
+
): InhibitorCommand {
|
|
76
|
+
return {
|
|
77
|
+
command: "sh",
|
|
78
|
+
args: [
|
|
79
|
+
"-c",
|
|
80
|
+
unixParentBoundScript(),
|
|
81
|
+
"pi-caffeinate-watch",
|
|
82
|
+
String(process.pid),
|
|
83
|
+
command,
|
|
84
|
+
...args,
|
|
85
|
+
],
|
|
86
|
+
description,
|
|
87
|
+
...(addDbusIdleInhibit ? { addDbusIdleInhibit: true } : {}),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function unixParentBoundScript() {
|
|
92
|
+
return `parent=$1; shift; "$@" & child=$!; ( while kill -0 "$parent" 2>/dev/null; do sleep 5; done; kill "$child" 2>/dev/null ) & watcher=$!; cleanup() { kill "$watcher" 2>/dev/null; kill "$child" 2>/dev/null; wait "$child" 2>/dev/null; }; trap 'cleanup; exit 0' INT TERM HUP EXIT; wait "$child"; status=$?; kill "$watcher" 2>/dev/null; trap - EXIT; exit "$status"`;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function commandExists(command: string) {
|
|
96
|
+
const searchPath = process.env.PATH ?? "";
|
|
97
|
+
const extensions = process.platform === "win32" ? ["", ".exe", ".cmd", ".bat"] : [""];
|
|
98
|
+
for (const directory of searchPath.split(process.platform === "win32" ? ";" : ":")) {
|
|
99
|
+
if (!directory) continue;
|
|
100
|
+
for (const extension of extensions) {
|
|
101
|
+
if (existsSync(path.join(directory, `${command}${extension}`))) return true;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function splitCommand(input: string) {
|
|
108
|
+
const parts: string[] = [];
|
|
109
|
+
let current = "";
|
|
110
|
+
let quote: '"' | "'" | undefined;
|
|
111
|
+
let escaping = false;
|
|
112
|
+
for (const char of input) {
|
|
113
|
+
if (escaping) {
|
|
114
|
+
current += char;
|
|
115
|
+
escaping = false;
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
if (char === "\\") {
|
|
119
|
+
escaping = true;
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if ((char === '"' || char === "'") && !quote) {
|
|
123
|
+
quote = char;
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
if (char === quote) {
|
|
127
|
+
quote = undefined;
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (/\s/.test(char) && !quote) {
|
|
131
|
+
if (current) {
|
|
132
|
+
parts.push(current);
|
|
133
|
+
current = "";
|
|
134
|
+
}
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
current += char;
|
|
138
|
+
}
|
|
139
|
+
if (current) parts.push(current);
|
|
140
|
+
return parts;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function windowsPowerInhibitorCommand(command: string, mode: CaffeinateMode): InhibitorCommand {
|
|
144
|
+
return {
|
|
145
|
+
command,
|
|
146
|
+
args: ["-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", windowsInhibitorScript(mode)],
|
|
147
|
+
description: `PowerShell SetThreadExecutionState (${formatMode(mode)})`,
|
|
148
|
+
releaseOnStdinClose: true,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export function windowsInhibitorScript(mode: CaffeinateMode) {
|
|
153
|
+
const flags = mode === "sleep" ? "0x80000001" : "0x80000003";
|
|
154
|
+
return `$ErrorActionPreference = 'Stop'; Add-Type -Namespace Native -Name Power -MemberDefinition '[DllImport("kernel32.dll")] public static extern uint SetThreadExecutionState(uint esFlags);'; $flags = [uint32]'${flags}'; $release = [uint32]'0x80000000'; $stdin = [Console]::OpenStandardInput(); $buffer = New-Object byte[] 1; $readTask = $stdin.ReadAsync($buffer, 0, 1); try { while ($true) { [Native.Power]::SetThreadExecutionState($flags) | Out-Null; if ($readTask.Wait(30000)) { break } } } finally { [Native.Power]::SetThreadExecutionState($release) | Out-Null }`;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function isWsl() {
|
|
158
|
+
try {
|
|
159
|
+
return existsSync("/proc/sys/fs/binfmt_misc/WSLInterop");
|
|
160
|
+
} catch {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export function formatMode(mode: CaffeinateMode) {
|
|
166
|
+
return mode === "sleep" ? "system-awake" : "display-awake";
|
|
167
|
+
}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { constants } from "node:fs";
|
|
3
|
+
import { access, lstat, mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
|
+
import process from "node:process";
|
|
6
|
+
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
7
|
+
|
|
8
|
+
const NEW_SETTINGS_FILE = "pi-caffeinate.json";
|
|
9
|
+
const LEGACY_SETTINGS_FILE = "pi-caffeinate-settings.json";
|
|
10
|
+
|
|
11
|
+
export type CaffeinateMode = "sleep" | "display";
|
|
12
|
+
|
|
13
|
+
export interface CaffeinateSettings {
|
|
14
|
+
mode: CaffeinateMode;
|
|
15
|
+
quiet: boolean;
|
|
16
|
+
updatedAt: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface SettingsFileOperations {
|
|
20
|
+
write(path: string, data: string): Promise<void>;
|
|
21
|
+
rename(source: string, destination: string): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const DEFAULT_FILE_OPERATIONS: SettingsFileOperations = {
|
|
25
|
+
write: (path, data) => writeFile(path, data, "utf8").then(() => undefined),
|
|
26
|
+
rename,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type SettingsLoadResult =
|
|
30
|
+
| { kind: "missing"; notice?: string }
|
|
31
|
+
| { kind: "invalid"; reason: string; notice?: string }
|
|
32
|
+
| { kind: "loaded"; settings: CaffeinateSettings; notice?: string };
|
|
33
|
+
|
|
34
|
+
export async function loadSettings(): Promise<SettingsLoadResult> {
|
|
35
|
+
await settingsSaveQueue;
|
|
36
|
+
const newPath = settingsFilePath();
|
|
37
|
+
const newSettings = await readSettingsFile(newPath);
|
|
38
|
+
if (newSettings.kind !== "missing") return withLegacyIgnoredNotice(newSettings);
|
|
39
|
+
|
|
40
|
+
const legacyPath = legacySettingsFilePath();
|
|
41
|
+
const legacySettings = await readSettingsFile(legacyPath);
|
|
42
|
+
const concurrentlyCreatedSettings = await readSettingsFile(newPath);
|
|
43
|
+
if (concurrentlyCreatedSettings.kind !== "missing") {
|
|
44
|
+
return withLegacyIgnoredNotice(concurrentlyCreatedSettings);
|
|
45
|
+
}
|
|
46
|
+
if (legacySettings.kind === "missing") return { kind: "missing" };
|
|
47
|
+
if (legacySettings.kind === "invalid") return legacySettings;
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
...legacySettings,
|
|
51
|
+
notice: `Using legacy ${LEGACY_SETTINGS_FILE}; rename it to ${NEW_SETTINGS_FILE}. Future saves write ${NEW_SETTINGS_FILE} without modifying the legacy file.`,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
interface SettingsDocumentResult {
|
|
56
|
+
result: SettingsLoadResult;
|
|
57
|
+
document?: Record<string, unknown>;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async function readSettingsDocument(filePath: string): Promise<SettingsDocumentResult> {
|
|
61
|
+
let text: string;
|
|
62
|
+
try {
|
|
63
|
+
text = await readFile(filePath, "utf8");
|
|
64
|
+
} catch (error) {
|
|
65
|
+
if (isNodeError(error) && error.code === "ENOENT") return { result: { kind: "missing" } };
|
|
66
|
+
return { result: { kind: "invalid", reason: `${filePath}: ${formatError(error)}` } };
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
const document = JSON.parse(text) as unknown;
|
|
70
|
+
const settings = normalizeCaffeinateSettings(document);
|
|
71
|
+
if (settings) {
|
|
72
|
+
return {
|
|
73
|
+
result: { kind: "loaded", settings },
|
|
74
|
+
document: { ...(document as Record<string, unknown>) },
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
result: {
|
|
79
|
+
kind: "invalid",
|
|
80
|
+
reason: `${filePath}: expected { "mode": "sleep" | "display", optional "quiet": boolean }`,
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
} catch (error) {
|
|
84
|
+
return { result: { kind: "invalid", reason: `${filePath}: ${formatError(error)}` } };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async function readSettingsFile(filePath: string): Promise<SettingsLoadResult> {
|
|
89
|
+
return (await readSettingsDocument(filePath)).result;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function withLegacyIgnoredNotice(settings: SettingsLoadResult): Promise<SettingsLoadResult> {
|
|
93
|
+
if (!(await fileExists(legacySettingsFilePath()))) return settings;
|
|
94
|
+
return {
|
|
95
|
+
...settings,
|
|
96
|
+
notice: `pi-caffeinate legacy settings ignored: ${legacySettingsFilePath()} exists, but ${settingsFilePath()} takes precedence. Delete ${LEGACY_SETTINGS_FILE} after confirming your settings.`,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async function fileExists(filePath: string) {
|
|
101
|
+
try {
|
|
102
|
+
await access(filePath, constants.F_OK);
|
|
103
|
+
return true;
|
|
104
|
+
} catch {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async function pathEntryExists(filePath: string) {
|
|
110
|
+
try {
|
|
111
|
+
await lstat(filePath);
|
|
112
|
+
return true;
|
|
113
|
+
} catch (error) {
|
|
114
|
+
if (isNodeError(error) && error.code === "ENOENT") return false;
|
|
115
|
+
throw error;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function normalizeCaffeinateSettings(value: unknown): CaffeinateSettings | undefined {
|
|
120
|
+
if (!value || typeof value !== "object") return undefined;
|
|
121
|
+
const settings = value as { mode?: unknown; quiet?: unknown; updatedAt?: unknown };
|
|
122
|
+
if (!isCaffeinateMode(settings.mode)) return undefined;
|
|
123
|
+
if (settings.quiet !== undefined && typeof settings.quiet !== "boolean") return undefined;
|
|
124
|
+
if (settings.updatedAt !== undefined && typeof settings.updatedAt !== "number") return undefined;
|
|
125
|
+
return {
|
|
126
|
+
mode: settings.mode,
|
|
127
|
+
quiet: settings.quiet ?? false,
|
|
128
|
+
updatedAt: settings.updatedAt ?? 0,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function isCaffeinateMode(value: unknown): value is CaffeinateMode {
|
|
133
|
+
return value === "sleep" || value === "display";
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
let settingsSaveQueue: Promise<unknown> = Promise.resolve();
|
|
137
|
+
|
|
138
|
+
export function saveSettings(
|
|
139
|
+
settings: Omit<CaffeinateSettings, "quiet"> & { quiet?: boolean },
|
|
140
|
+
operations: Partial<SettingsFileOperations> = {},
|
|
141
|
+
): Promise<CaffeinateSettings> {
|
|
142
|
+
const operation = settingsSaveQueue.then(() => saveSettingsNow(settings, operations));
|
|
143
|
+
settingsSaveQueue = operation.catch(() => undefined);
|
|
144
|
+
return operation;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async function saveSettingsNow(
|
|
148
|
+
settings: Omit<CaffeinateSettings, "quiet"> & { quiet?: boolean },
|
|
149
|
+
operations: Partial<SettingsFileOperations>,
|
|
150
|
+
): Promise<CaffeinateSettings> {
|
|
151
|
+
const filePath = settingsFilePath();
|
|
152
|
+
let current = await readSettingsDocument(filePath);
|
|
153
|
+
const replaceCanonical = current.result.kind !== "missing";
|
|
154
|
+
if (!replaceCanonical) current = await readSettingsDocument(legacySettingsFilePath());
|
|
155
|
+
if (current.result.kind === "invalid") {
|
|
156
|
+
throw new Error(`Cannot save pi-caffeinate settings until you repair ${current.result.reason}`);
|
|
157
|
+
}
|
|
158
|
+
const document = current.document ?? {};
|
|
159
|
+
const quiet =
|
|
160
|
+
settings.quiet ?? (current.result.kind === "loaded" ? current.result.settings.quiet : false);
|
|
161
|
+
const nextSettings = { mode: settings.mode, quiet, updatedAt: settings.updatedAt };
|
|
162
|
+
const nextDocument = {
|
|
163
|
+
...document,
|
|
164
|
+
...nextSettings,
|
|
165
|
+
};
|
|
166
|
+
await mkdir(dirname(filePath), { recursive: true });
|
|
167
|
+
const tempFile = `${filePath}.${process.pid}.${randomUUID()}.tmp`;
|
|
168
|
+
try {
|
|
169
|
+
await (operations.write ?? DEFAULT_FILE_OPERATIONS.write)(
|
|
170
|
+
tempFile,
|
|
171
|
+
`${JSON.stringify(nextDocument, null, 2)}\n`,
|
|
172
|
+
);
|
|
173
|
+
if (!replaceCanonical && (await pathEntryExists(filePath))) {
|
|
174
|
+
throw new Error(`${NEW_SETTINGS_FILE} was created concurrently; reopen settings and retry.`);
|
|
175
|
+
}
|
|
176
|
+
await (operations.rename ?? DEFAULT_FILE_OPERATIONS.rename)(tempFile, filePath);
|
|
177
|
+
return nextSettings;
|
|
178
|
+
} catch (error) {
|
|
179
|
+
await rm(tempFile, { force: true }).catch(() => undefined);
|
|
180
|
+
throw error;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export function settingsFilePath() {
|
|
185
|
+
return join(agentDir(), NEW_SETTINGS_FILE);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function legacySettingsFilePath() {
|
|
189
|
+
return join(agentDir(), LEGACY_SETTINGS_FILE);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function agentDir() {
|
|
193
|
+
return getAgentDir();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function isNodeError(error: unknown): error is NodeJS.ErrnoException {
|
|
197
|
+
return error instanceof Error && "code" in error;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function formatError(error: unknown) {
|
|
201
|
+
return error instanceof Error ? error.message : String(error);
|
|
202
|
+
}
|
|
@@ -67,18 +67,20 @@ Optional config file at `<agent-dir>/extensions/fast-mode.json` (typically
|
|
|
67
67
|
"openai/gpt-5.6-sol",
|
|
68
68
|
"openai/gpt-5.6-terra",
|
|
69
69
|
"openai/gpt-5.6-luna",
|
|
70
|
+
"openai/gpt-6-astra",
|
|
70
71
|
"openai-codex/gpt-5.4",
|
|
71
72
|
"openai-codex/gpt-5.5",
|
|
72
73
|
"openai-codex/gpt-5.6-sol",
|
|
73
74
|
"openai-codex/gpt-5.6-terra",
|
|
74
|
-
"openai-codex/gpt-5.6-luna"
|
|
75
|
+
"openai-codex/gpt-5.6-luna",
|
|
76
|
+
"openai-codex/gpt-6-astra"
|
|
75
77
|
],
|
|
76
78
|
"showStatus": true
|
|
77
79
|
}
|
|
78
80
|
```
|
|
79
81
|
|
|
80
|
-
- `enabled`: fast-mode state at session start (`/fast` overrides it for the session
|
|
81
|
-
the toggle
|
|
82
|
+
- `enabled`: fast-mode state at session start (`/fast` overrides it for the session
|
|
83
|
+
without writing the toggle back to the file).
|
|
82
84
|
- `models`: the `provider/model-id` keys fast mode applies to. The defaults above are
|
|
83
85
|
used when the file is absent. Models whose API has no fast-mode support are
|
|
84
86
|
ignored.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;iBAuEwB,SAAS,IAAI"}
|