@herbertgao/pi-extensions 2026.8.13 → 2026.8.15
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 +19 -14
- package/THIRD_PARTY_NOTICES.md +0 -1
- package/node_modules/@czottmann/pi-automode/CHANGELOG.md +19 -0
- package/node_modules/@czottmann/pi-automode/README.md +5 -1
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/classifier.ts +126 -13
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/config.ts +7 -3
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/constants.ts +2 -0
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/hard-deny.ts +134 -23
- package/node_modules/@czottmann/pi-automode/package.json +1 -1
- package/node_modules/@herbertgao/{pi-stash → pi-bark}/LICENSE +4 -5
- package/node_modules/@herbertgao/pi-bark/README.md +44 -0
- package/node_modules/@herbertgao/pi-bark/assets/pi-icon.png +0 -0
- package/node_modules/@herbertgao/pi-bark/package.json +53 -0
- package/node_modules/@herbertgao/pi-bark/src/index.ts +178 -0
- package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +6 -0
- package/node_modules/@herbertgao/pi-subagents/package.json +2 -1
- package/node_modules/@herbertgao/pi-subagents/src/ui/conversation-viewer.ts +8 -1
- package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +2 -2
- package/node_modules/@narumitw/pi-btw/README.md +125 -88
- package/node_modules/@narumitw/pi-btw/dist/index.ts +140 -45
- package/node_modules/@narumitw/pi-btw/dist/index.ts.map +2 -2
- package/node_modules/@narumitw/pi-btw/package.json +5 -8
- package/node_modules/@narumitw/pi-btw/src/btw.ts +31 -26
- package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +106 -17
- package/node_modules/@narumitw/pi-btw/src/menu.ts +34 -2
- package/node_modules/@narumitw/pi-btw/src/settings.ts +16 -0
- package/node_modules/@tifan/pi-handoff/README.md +36 -13
- package/node_modules/@tifan/pi-handoff/package.json +2 -2
- package/node_modules/@tifan/pi-handoff/src/index.ts +160 -4
- package/node_modules/@tifan/pi-preferred-thinking/README.md +1 -1
- package/node_modules/@tifan/pi-preferred-thinking/package.json +1 -1
- package/node_modules/@tifan/pi-preferred-thinking/src/index.ts +15 -2
- package/node_modules/@tifan/pi-recap/README.md +1 -1
- package/node_modules/@tifan/pi-recap/package.json +2 -2
- package/node_modules/@tifan/pi-recap/src/index.ts +15 -0
- package/node_modules/@tifan/pi-rename/README.md +42 -21
- package/node_modules/@tifan/pi-rename/package.json +1 -1
- package/node_modules/@tifan/pi-rename/src/index.ts +62 -11
- package/node_modules/@tifan/pi-rename/src/language.ts +18 -0
- package/node_modules/@tifan/pi-rename/src/models.ts +69 -13
- package/node_modules/@tifan/pi-rename/src/naming.ts +36 -7
- package/node_modules/@tifan/pi-rename/src/sanitize.ts +22 -14
- package/node_modules/pi-lens/CHANGELOG.md +320 -0
- package/node_modules/pi-lens/config/dependency-cruiser-eager-allowlist.json +79 -0
- package/node_modules/pi-lens/dist/clients/actionable-warnings-logger.js +16 -1
- package/node_modules/pi-lens/dist/clients/ast-grep-client.js +13 -6
- package/node_modules/pi-lens/dist/clients/availability-probe-flight.js +12 -0
- package/node_modules/pi-lens/dist/clients/biome-client.js +7 -0
- package/node_modules/pi-lens/dist/clients/blocker-freshness.js +20 -0
- package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +56 -19
- package/node_modules/pi-lens/dist/clients/build-identity.js +95 -0
- package/node_modules/pi-lens/dist/clients/bus-publish.js +3 -0
- package/node_modules/pi-lens/dist/clients/cache/rule-cache.js +2 -1
- package/node_modules/pi-lens/dist/clients/cache-observability.js +2 -1
- package/node_modules/pi-lens/dist/clients/cascade-logger.js +15 -1
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +14 -11
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +56 -4
- package/node_modules/pi-lens/dist/clients/demoted-finding-render.js +14 -0
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +20 -3
- package/node_modules/pi-lens/dist/clients/deps/minimatch.js +1 -1
- package/node_modules/pi-lens/dist/clients/dispatch/collect-later-tier.js +39 -0
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +150 -9
- package/node_modules/pi-lens/dist/clients/dispatch/fact-store.js +231 -9
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +205 -100
- package/node_modules/pi-lens/dist/clients/dispatch/pending-runner-findings.js +87 -0
- package/node_modules/pi-lens/dist/clients/dispatch/plan.js +21 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +174 -55
- package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +5 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +16 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +54 -9
- package/node_modules/pi-lens/dist/clients/dispatch/runners/index.js +1 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +37 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +4 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +11 -4
- package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +4 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +8 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +76 -25
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +4 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/tool-failure.js +19 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +7 -13
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +51 -17
- package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +66 -1
- package/node_modules/pi-lens/dist/clients/file-utils.js +157 -7
- package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +5 -0
- package/node_modules/pi-lens/dist/clients/formatters.js +28 -3
- package/node_modules/pi-lens/dist/clients/git-guard.js +197 -47
- package/node_modules/pi-lens/dist/clients/git-tracked-ignore.js +32 -1
- package/node_modules/pi-lens/dist/clients/govulncheck-client.js +5 -1
- package/node_modules/pi-lens/dist/clients/gzip-stage-write.js +7 -0
- package/node_modules/pi-lens/dist/clients/installer/index.js +131 -34
- package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh.js +3 -1
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +4 -13
- package/node_modules/pi-lens/dist/clients/instance-registry-lock.js +145 -0
- package/node_modules/pi-lens/dist/clients/instance-registry.js +432 -122
- package/node_modules/pi-lens/dist/clients/jscpd-client.js +6 -1
- package/node_modules/pi-lens/dist/clients/language-profile.js +4 -2
- package/node_modules/pi-lens/dist/clients/latency-logger.js +19 -1
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +8 -0
- package/node_modules/pi-lens/dist/clients/lens-map.js +3 -1
- package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +4 -0
- package/node_modules/pi-lens/dist/clients/lsp/client.js +516 -31
- package/node_modules/pi-lens/dist/clients/lsp/config.js +25 -2
- package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +9 -4
- package/node_modules/pi-lens/dist/clients/lsp/index.js +509 -182
- package/node_modules/pi-lens/dist/clients/lsp/jvm-runtime.js +5 -0
- package/node_modules/pi-lens/dist/clients/lsp/launch.js +36 -8
- package/node_modules/pi-lens/dist/clients/lsp/pending-aux-coverage.js +116 -4
- package/node_modules/pi-lens/dist/clients/lsp/server.js +142 -13
- package/node_modules/pi-lens/dist/clients/lsp/session-roots.js +99 -0
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +16 -6
- package/node_modules/pi-lens/dist/clients/lsp/workspace-sweep-hold.js +32 -23
- package/node_modules/pi-lens/dist/clients/lsp-mutation.js +16 -2
- package/node_modules/pi-lens/dist/clients/mcp/analyze.js +12 -6
- package/node_modules/pi-lens/dist/clients/mcp/session.js +14 -1
- package/node_modules/pi-lens/dist/clients/memory-sampler.js +23 -1
- package/node_modules/pi-lens/dist/clients/message-end-attribution.js +30 -0
- package/node_modules/pi-lens/dist/clients/metrics-history.js +21 -4
- package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +232 -18
- package/node_modules/pi-lens/dist/clients/package-manager.js +6 -18
- package/node_modules/pi-lens/dist/clients/path-keyed-map.js +14 -1
- package/node_modules/pi-lens/dist/clients/path-utils.js +32 -0
- package/node_modules/pi-lens/dist/clients/pipeline.js +0 -8
- package/node_modules/pi-lens/dist/clients/process-singletons.js +210 -0
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/madge.js +2 -1
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +10 -4
- package/node_modules/pi-lens/dist/clients/project-snapshot.js +33 -11
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +24 -2
- package/node_modules/pi-lens/dist/clients/read-guard.js +74 -7
- package/node_modules/pi-lens/dist/clients/recent-touches.js +17 -5
- package/node_modules/pi-lens/dist/clients/review-graph/builder.js +639 -62
- package/node_modules/pi-lens/dist/clients/review-graph/tsconfig-paths.js +5 -1
- package/node_modules/pi-lens/dist/clients/review-graph-logger.js +21 -1
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +68 -0
- package/node_modules/pi-lens/dist/clients/runtime-session.js +30 -12
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +15 -0
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +106 -7
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +242 -27
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +158 -18
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +48 -17
- package/node_modules/pi-lens/dist/clients/session-lifecycle.js +238 -42
- package/node_modules/pi-lens/dist/clients/sg-runner.js +27 -15
- package/node_modules/pi-lens/dist/clients/shared-checkout-guard.js +338 -0
- package/node_modules/pi-lens/dist/clients/spawn-output-cap.js +37 -0
- package/node_modules/pi-lens/dist/clients/spawn-timeout-cooldown.js +15 -1
- package/node_modules/pi-lens/dist/clients/startup-scan.js +6 -7
- package/node_modules/pi-lens/dist/clients/startup-timing.js +69 -4
- package/node_modules/pi-lens/dist/clients/string-utils.js +20 -0
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +419 -88
- package/node_modules/pi-lens/dist/clients/tool-policy.js +1 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +11 -5
- package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +17 -1
- package/node_modules/pi-lens/dist/clients/warm-attach.js +8 -10
- package/node_modules/pi-lens/dist/clients/word-index-logger.js +13 -1
- package/node_modules/pi-lens/dist/clients/word-index-store.js +448 -0
- package/node_modules/pi-lens/dist/clients/word-index.js +582 -104
- package/node_modules/pi-lens/dist/clients/workspace-topology.js +17 -0
- package/node_modules/pi-lens/dist/clients/zizmor-config.js +26 -6
- package/node_modules/pi-lens/dist/index.js +11243 -6651
- package/node_modules/pi-lens/dist/mcp/build-staleness.js +8 -7
- package/node_modules/pi-lens/dist/mcp/cli.js +3 -1
- package/node_modules/pi-lens/dist/mcp/server.js +6 -1
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +4 -0
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +14 -5
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +3 -1
- package/node_modules/pi-lens/docs/agent-guide.md +4 -2
- package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +41 -10
- package/node_modules/pi-lens/docs/astplayground.md +26 -17
- package/node_modules/pi-lens/package.json +5 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/c-no-malloc-free-test.yml +20 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/cpp-no-malloc-free-test.yml +25 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/cpp-no-printf-test.yml +19 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/go-no-fmt-println-test.yml +19 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/go-no-panic-in-lib-test.yml +17 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/go-no-underscore-func-name-test.yml +18 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/go-prefer-errors-is-test.yml +15 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/go-prefer-string-builder-test.yml +21 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/hyphenated-svg-attribute-test.yml +11 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/kotlin-no-lateinit-test.yml +17 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/kotlin-no-nullable-boolean-test.yml +15 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/kotlin-no-println-test.yml +19 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/kotlin-no-unnecessary-let-test.yml +7 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/kotlin-no-unsafe-cast-test.yml +7 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/kotlin-no-var-test.yml +7 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/kotlin-prefer-data-class-test.yml +25 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/kotlin-prefer-is-empty-test.yml +11 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-important-test.yml +21 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-raw-types-test.yml +30 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-string-concat-in-loop-test.yml +100 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-system-out-println-test.yml +7 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/prefer-string-is-empty-test.yml +7 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/python-optional-type-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/reducible-list-comprehension-test.yml +11 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/ruby-symbol-to-proc-candidate-test.yml +10 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/rust-no-chars-enumerate-test.yml +7 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/c-no-malloc-free.yml +39 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/cpp-no-malloc-free.yml +45 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/cpp-no-printf.yml +41 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/go-no-fmt-println.yml +43 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/go-no-panic-in-lib.yml +41 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/go-no-underscore-func-name.yml +35 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/go-prefer-errors-is.yml +40 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/go-prefer-string-builder.yml +43 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/hyphenated-svg-attribute.yml +32 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/kotlin-no-lateinit.yml +37 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/kotlin-no-nullable-boolean.yml +33 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/kotlin-no-println.yml +42 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/kotlin-no-unnecessary-let.yml +28 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/kotlin-no-unsafe-cast.yml +28 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/kotlin-no-var.yml +35 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/kotlin-prefer-data-class.yml +66 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/kotlin-prefer-is-empty.yml +35 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-important.yml +21 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-raw-types.yml +33 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-string-concat-in-loop.yml +90 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-system-out-println.yml +16 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/prefer-string-is-empty.yml +11 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/python-optional-type.yml +22 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/reducible-list-comprehension.yml +29 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/ruby-symbol-to-proc-candidate.yml +25 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/rust-no-chars-enumerate.yml +19 -0
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +35 -0
- package/node_modules/pi-mcp-adapter/README.md +5 -2
- package/node_modules/pi-mcp-adapter/cli.js +4 -4
- package/node_modules/pi-mcp-adapter/commands.ts +1 -1
- package/node_modules/pi-mcp-adapter/config.ts +1 -0
- package/node_modules/pi-mcp-adapter/dist/config.js +1 -0
- package/node_modules/pi-mcp-adapter/dist/config.js.map +1 -1
- package/node_modules/pi-mcp-adapter/dist/mcp-bearer-store.d.ts +24 -0
- package/node_modules/pi-mcp-adapter/dist/mcp-bearer-store.js +336 -0
- package/node_modules/pi-mcp-adapter/dist/mcp-bearer-store.js.map +1 -0
- package/node_modules/pi-mcp-adapter/dist/types.d.ts +3 -1
- package/node_modules/pi-mcp-adapter/dist/types.js.map +1 -1
- package/node_modules/pi-mcp-adapter/index.ts +90 -6
- package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +124 -32
- package/node_modules/pi-mcp-adapter/mcp-bearer-store.ts +0 -2
- package/node_modules/pi-mcp-adapter/mcp-oauth-provider.ts +89 -0
- package/node_modules/pi-mcp-adapter/mcp-references.ts +9 -1
- package/node_modules/pi-mcp-adapter/package.json +1 -1
- package/node_modules/pi-mcp-adapter/proxy-modes.ts +62 -22
- package/node_modules/pi-mcp-adapter/request-headers-command.ts +1 -1
- package/node_modules/pi-mcp-adapter/server-manager.ts +6 -0
- package/node_modules/pi-mcp-adapter/types.ts +3 -1
- package/node_modules/pi-web-access/CHANGELOG.md +42 -0
- package/node_modules/pi-web-access/README.md +26 -10
- package/node_modules/pi-web-access/curator-page.ts +12 -3
- package/node_modules/pi-web-access/curator-server.ts +3 -1
- package/node_modules/pi-web-access/extract.ts +88 -13
- package/node_modules/pi-web-access/gemini-search.ts +10 -5
- package/node_modules/pi-web-access/github-extract.ts +47 -3
- package/node_modules/pi-web-access/index.ts +40 -40
- package/node_modules/pi-web-access/package.json +1 -1
- package/node_modules/pi-web-access/page-query.ts +61 -8
- package/node_modules/pi-web-access/xcrawl.ts +264 -0
- package/package.json +19 -22
- package/node_modules/@herbertgao/pi-stash/README.md +0 -34
- package/node_modules/@herbertgao/pi-stash/package.json +0 -51
- package/node_modules/@herbertgao/pi-stash/src/index.ts +0 -118
- package/node_modules/@tifan/pi-titlebar-spinner/README.md +0 -24
- package/node_modules/@tifan/pi-titlebar-spinner/package.json +0 -39
- package/node_modules/@tifan/pi-titlebar-spinner/src/index.ts +0 -49
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto"
|
|
1
2
|
import type { AgentMessage } from "@earendil-works/pi-agent-core"
|
|
2
3
|
import type { Message } from "@earendil-works/pi-ai/compat"
|
|
3
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
generateRename,
|
|
6
|
+
getUserMessageContext,
|
|
7
|
+
resolveInitialModelConfig,
|
|
8
|
+
} from "@tifan/pi-rename/naming"
|
|
4
9
|
import type {
|
|
5
10
|
ExtensionAPI,
|
|
6
11
|
ExtensionCommandContext,
|
|
@@ -10,6 +15,7 @@ import {
|
|
|
10
15
|
BorderedLoader,
|
|
11
16
|
convertToLlm,
|
|
12
17
|
serializeConversation,
|
|
18
|
+
SessionManager,
|
|
13
19
|
sessionEntryToContextMessages,
|
|
14
20
|
} from "@earendil-works/pi-coding-agent"
|
|
15
21
|
import { completeText } from "./complete-text.js"
|
|
@@ -77,6 +83,17 @@ async function nextHandoffPath(slug: string): Promise<string> {
|
|
|
77
83
|
throw new Error("Could not allocate a unique handoff file path")
|
|
78
84
|
}
|
|
79
85
|
|
|
86
|
+
async function generateSessionName(
|
|
87
|
+
ctx: ExtensionCommandContext,
|
|
88
|
+
messages: readonly AgentMessage[],
|
|
89
|
+
): Promise<string> {
|
|
90
|
+
const context = getUserMessageContext(messages)
|
|
91
|
+
if (!context) return "handoff-session"
|
|
92
|
+
|
|
93
|
+
const result = await generateRename(ctx, resolveInitialModelConfig(), context)
|
|
94
|
+
return result?.name ?? "handoff-session"
|
|
95
|
+
}
|
|
96
|
+
|
|
80
97
|
function buildNewSessionPrompt(handoffPath: string): string {
|
|
81
98
|
return [
|
|
82
99
|
"Continue from this handoff:",
|
|
@@ -85,6 +102,133 @@ function buildNewSessionPrompt(handoffPath: string): string {
|
|
|
85
102
|
].join("\n\n")
|
|
86
103
|
}
|
|
87
104
|
|
|
105
|
+
type HerdrTabCreateResponse = {
|
|
106
|
+
result?: {
|
|
107
|
+
root_pane?: {
|
|
108
|
+
pane_id?: unknown
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function getHerdrWorkspaceId(): string | undefined {
|
|
114
|
+
if (process.env["HERDR_ENV"] !== "1") return undefined
|
|
115
|
+
|
|
116
|
+
const workspaceId = process.env["HERDR_WORKSPACE_ID"]?.trim()
|
|
117
|
+
if (!workspaceId) {
|
|
118
|
+
throw new Error("Herdr workspace context is unavailable")
|
|
119
|
+
}
|
|
120
|
+
return workspaceId
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function getHerdrRootPaneId(stdout: string): string | undefined {
|
|
124
|
+
try {
|
|
125
|
+
const response = JSON.parse(stdout) as HerdrTabCreateResponse
|
|
126
|
+
const paneId = response.result?.root_pane?.pane_id
|
|
127
|
+
return typeof paneId === "string" && paneId.trim() ? paneId : undefined
|
|
128
|
+
} catch {
|
|
129
|
+
return undefined
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function getCommandError(stdout: string, stderr: string): string {
|
|
134
|
+
return stderr.trim() || stdout.trim() || "unknown error"
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async function startHandoffInHerdr(options: {
|
|
138
|
+
pi: ExtensionAPI
|
|
139
|
+
ctx: ExtensionCommandContext
|
|
140
|
+
handoffPath: string
|
|
141
|
+
parentSession: string | undefined
|
|
142
|
+
sessionName: string
|
|
143
|
+
workspaceId: string
|
|
144
|
+
}): Promise<void> {
|
|
145
|
+
const childSessionManager = SessionManager.create(
|
|
146
|
+
options.ctx.cwd,
|
|
147
|
+
undefined,
|
|
148
|
+
options.parentSession
|
|
149
|
+
? { parentSession: options.parentSession }
|
|
150
|
+
: undefined,
|
|
151
|
+
)
|
|
152
|
+
const childSessionPath = childSessionManager.getSessionFile()
|
|
153
|
+
const childSessionHeader = childSessionManager.getHeader()
|
|
154
|
+
if (!childSessionPath || !childSessionHeader) {
|
|
155
|
+
throw new Error("Could not create a persisted handoff session")
|
|
156
|
+
}
|
|
157
|
+
await mkdir(childSessionManager.getSessionDir(), { recursive: true })
|
|
158
|
+
await writeFile(childSessionPath, `${JSON.stringify(childSessionHeader)}\n`, {
|
|
159
|
+
flag: "wx",
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
const createdTab = await options.pi.exec(
|
|
163
|
+
"herdr",
|
|
164
|
+
[
|
|
165
|
+
"tab",
|
|
166
|
+
"create",
|
|
167
|
+
"--workspace",
|
|
168
|
+
options.workspaceId,
|
|
169
|
+
"--cwd",
|
|
170
|
+
options.ctx.cwd,
|
|
171
|
+
"--label",
|
|
172
|
+
options.sessionName,
|
|
173
|
+
"--focus",
|
|
174
|
+
],
|
|
175
|
+
{ timeout: 5_000 },
|
|
176
|
+
)
|
|
177
|
+
if (createdTab.code !== 0) {
|
|
178
|
+
throw new Error(
|
|
179
|
+
`Could not create Herdr tab: ${getCommandError(createdTab.stdout, createdTab.stderr)}`,
|
|
180
|
+
)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const rootPaneId = getHerdrRootPaneId(createdTab.stdout)
|
|
184
|
+
if (!rootPaneId) {
|
|
185
|
+
throw new Error("Could not find the new Herdr tab's root pane")
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const agentName = `handoff-${randomUUID().slice(0, 8)}`
|
|
189
|
+
const model = options.ctx.model!
|
|
190
|
+
|
|
191
|
+
const startedAgent = await options.pi.exec(
|
|
192
|
+
"herdr",
|
|
193
|
+
[
|
|
194
|
+
"agent",
|
|
195
|
+
"start",
|
|
196
|
+
agentName,
|
|
197
|
+
"--kind",
|
|
198
|
+
"pi",
|
|
199
|
+
"--pane",
|
|
200
|
+
rootPaneId,
|
|
201
|
+
"--",
|
|
202
|
+
"--session",
|
|
203
|
+
childSessionPath,
|
|
204
|
+
"--name",
|
|
205
|
+
options.sessionName,
|
|
206
|
+
"--provider",
|
|
207
|
+
model.provider,
|
|
208
|
+
"--model",
|
|
209
|
+
model.id,
|
|
210
|
+
],
|
|
211
|
+
{ timeout: 35_000 },
|
|
212
|
+
)
|
|
213
|
+
if (startedAgent.code !== 0) {
|
|
214
|
+
throw new Error(
|
|
215
|
+
`Could not start Pi in Herdr tab: ${getCommandError(startedAgent.stdout, startedAgent.stderr)}`,
|
|
216
|
+
)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const promptedAgent = await options.pi.exec("herdr", [
|
|
220
|
+
"agent",
|
|
221
|
+
"prompt",
|
|
222
|
+
agentName,
|
|
223
|
+
buildNewSessionPrompt(options.handoffPath),
|
|
224
|
+
])
|
|
225
|
+
if (promptedAgent.code !== 0) {
|
|
226
|
+
throw new Error(
|
|
227
|
+
`Could not send the handoff prompt: ${getCommandError(promptedAgent.stdout, promptedAgent.stderr)}`,
|
|
228
|
+
)
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
88
232
|
function buildDocumentWithMetadata(options: {
|
|
89
233
|
generated: string
|
|
90
234
|
focus: string
|
|
@@ -250,9 +394,7 @@ async function runHandoff(
|
|
|
250
394
|
return
|
|
251
395
|
}
|
|
252
396
|
|
|
253
|
-
const sessionName =
|
|
254
|
-
sanitizeRenameText(ctx.sessionManager.getSessionName() ?? focus) ||
|
|
255
|
-
"handoff-session"
|
|
397
|
+
const sessionName = await generateSessionName(ctx, messages)
|
|
256
398
|
const handoffPath = await nextHandoffPath(sessionName)
|
|
257
399
|
const document = buildDocumentWithMetadata({
|
|
258
400
|
generated,
|
|
@@ -262,6 +404,20 @@ async function runHandoff(
|
|
|
262
404
|
})
|
|
263
405
|
await writeFile(handoffPath, document, "utf8")
|
|
264
406
|
|
|
407
|
+
const herdrWorkspaceId = getHerdrWorkspaceId()
|
|
408
|
+
if (herdrWorkspaceId) {
|
|
409
|
+
await startHandoffInHerdr({
|
|
410
|
+
pi,
|
|
411
|
+
ctx,
|
|
412
|
+
handoffPath,
|
|
413
|
+
parentSession,
|
|
414
|
+
sessionName,
|
|
415
|
+
workspaceId: herdrWorkspaceId,
|
|
416
|
+
})
|
|
417
|
+
ctx.ui.notify(`Handoff opened in a new Herdr tab: ${handoffPath}`, "info")
|
|
418
|
+
return
|
|
419
|
+
}
|
|
420
|
+
|
|
265
421
|
await ctx.newSession({
|
|
266
422
|
...(parentSession ? { parentSession } : {}),
|
|
267
423
|
setup: async (sessionManager) => {
|
|
@@ -41,7 +41,7 @@ The extension requires `enabledModels` to exist before it can save a pin. If
|
|
|
41
41
|
the selected model is not listed, it adds an exact entry without removing other
|
|
42
42
|
models or patterns.
|
|
43
43
|
|
|
44
|
-
The old
|
|
44
|
+
The old `$PI_CODING_AGENT_DIR/extensions/pi-preferred-thinking.json` file is no longer
|
|
45
45
|
read. Existing users must move preferences to `enabledModels` or set them with
|
|
46
46
|
`/preferred-thinking`.
|
|
47
47
|
|
|
@@ -138,6 +138,15 @@ function showHint(ctx: ExtensionContext, modelKey: string): void {
|
|
|
138
138
|
}, HINT_DURATION_MS)
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
+
function hasExplicitSubagentThinking(): boolean {
|
|
142
|
+
return (
|
|
143
|
+
Boolean(process.env["PI_SUBAGENT_ID"]) &&
|
|
144
|
+
process.argv.some(
|
|
145
|
+
(arg) => arg === "--thinking" || arg.startsWith("--thinking="),
|
|
146
|
+
)
|
|
147
|
+
)
|
|
148
|
+
}
|
|
149
|
+
|
|
141
150
|
function applyPreferredThinking(
|
|
142
151
|
pi: ExtensionAPI,
|
|
143
152
|
ctx: ExtensionContext,
|
|
@@ -210,11 +219,15 @@ export default function (pi: ExtensionAPI): void {
|
|
|
210
219
|
|
|
211
220
|
pi.on("session_start", async (_event, ctx) => {
|
|
212
221
|
nudgedModels.clear()
|
|
213
|
-
if (ctx.model
|
|
222
|
+
if (ctx.model && !hasExplicitSubagentThinking()) {
|
|
223
|
+
applyPreferredThinking(pi, ctx, ctx.model)
|
|
224
|
+
}
|
|
214
225
|
})
|
|
215
226
|
|
|
216
227
|
pi.on("model_select", async (event, ctx) => {
|
|
217
|
-
|
|
228
|
+
if (!hasExplicitSubagentThinking()) {
|
|
229
|
+
applyPreferredThinking(pi, ctx, event.model)
|
|
230
|
+
}
|
|
218
231
|
})
|
|
219
232
|
|
|
220
233
|
pi.on("session_shutdown", async (_event, ctx) => {
|
|
@@ -44,7 +44,7 @@ Run `/recap config` to choose a different model.
|
|
|
44
44
|
|
|
45
45
|
After you choose a model, `pi-recap` uses only that model. Choose `Use default` in `/recap config` to return to the default.
|
|
46
46
|
|
|
47
|
-
You can also edit
|
|
47
|
+
You can also edit `$PI_CODING_AGENT_DIR/extensions/pi-recap.json` manually:
|
|
48
48
|
|
|
49
49
|
```json
|
|
50
50
|
{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tifan/pi-recap",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.6",
|
|
4
4
|
"description": "One-line session recap on demand or after you have been away.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"provenance": true
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
|
-
"@earendil-works/pi-coding-agent": ">=0.84.
|
|
32
|
+
"@earendil-works/pi-coding-agent": ">=0.84.3"
|
|
33
33
|
},
|
|
34
34
|
"engines": {
|
|
35
35
|
"node": ">=20"
|
|
@@ -100,6 +100,7 @@ interface RecapState {
|
|
|
100
100
|
visible: boolean
|
|
101
101
|
stale: boolean
|
|
102
102
|
lastRecapCurrent: boolean
|
|
103
|
+
skipNextAwayRecap: boolean
|
|
103
104
|
abortController: AbortController | undefined
|
|
104
105
|
awayTimer: ReturnType<typeof setTimeout> | undefined
|
|
105
106
|
}
|
|
@@ -113,6 +114,7 @@ function createRecapState(): RecapState {
|
|
|
113
114
|
visible: false,
|
|
114
115
|
stale: false,
|
|
115
116
|
lastRecapCurrent: false,
|
|
117
|
+
skipNextAwayRecap: false,
|
|
116
118
|
abortController: undefined,
|
|
117
119
|
awayTimer: undefined,
|
|
118
120
|
}
|
|
@@ -140,6 +142,7 @@ function resetRecapSession(ctx: ExtensionContext, state: RecapState): void {
|
|
|
140
142
|
state.visible = false
|
|
141
143
|
state.stale = false
|
|
142
144
|
state.lastRecapCurrent = false
|
|
145
|
+
state.skipNextAwayRecap = false
|
|
143
146
|
clearAwayTimer(state)
|
|
144
147
|
abortPendingGeneration(state)
|
|
145
148
|
clearWidget(ctx)
|
|
@@ -551,13 +554,25 @@ export default function (pi: ExtensionAPI): void {
|
|
|
551
554
|
state.runId++
|
|
552
555
|
state.stale = false
|
|
553
556
|
state.lastRecapCurrent = false
|
|
557
|
+
state.skipNextAwayRecap = false
|
|
554
558
|
clearAwayTimer(state)
|
|
555
559
|
abortPendingGeneration(state)
|
|
556
560
|
hideRecap(ctx, state)
|
|
557
561
|
clearNoModelWarning(ctx)
|
|
558
562
|
})
|
|
559
563
|
|
|
564
|
+
pi.on("session_compact_failed", (event) => {
|
|
565
|
+
if (event.willRetry) return
|
|
566
|
+
state.skipNextAwayRecap = true
|
|
567
|
+
clearAwayTimer(state)
|
|
568
|
+
})
|
|
569
|
+
|
|
560
570
|
pi.on("agent_settled", (_event, ctx) => {
|
|
571
|
+
if (state.skipNextAwayRecap) {
|
|
572
|
+
state.skipNextAwayRecap = false
|
|
573
|
+
return
|
|
574
|
+
}
|
|
575
|
+
|
|
561
576
|
state.stale = true
|
|
562
577
|
scheduleAwayRecap(pi, ctx, state)
|
|
563
578
|
})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @tifan/pi-rename
|
|
2
2
|
|
|
3
|
-
Generate session names
|
|
3
|
+
Generate short pi session names and rename the current Herdr pane or tab to match.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -8,61 +8,82 @@ Generate session names for pi and Herdr.
|
|
|
8
8
|
pi install npm:@tifan/pi-rename
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Requires Pi 0.84.2 or newer.
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Usage
|
|
14
14
|
|
|
15
|
-
Run
|
|
15
|
+
Run:
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
```text
|
|
18
|
+
/rename
|
|
19
|
+
```
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
The extension:
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
- Builds context from the first user message and up to three latest user messages.
|
|
24
|
+
- Ignores assistant replies, tool output, and attachments.
|
|
25
|
+
- Redacts common secrets before sending context to the model.
|
|
26
|
+
- Creates a lowercase, hyphen-separated name of up to 30 characters.
|
|
27
|
+
- Falls back to the latest user message when the naming model is unavailable.
|
|
22
28
|
|
|
23
29
|
## Commands
|
|
24
30
|
|
|
25
31
|
- `/rename`: Generate and apply a session name.
|
|
26
32
|
- `/rename status`: Show model and rename status.
|
|
27
33
|
- `/rename config`: Choose a rename model.
|
|
34
|
+
- `/rename config language <auto|BCP-47>`: Set session-name language.
|
|
28
35
|
- `/rename help`: List rename commands.
|
|
29
36
|
|
|
30
|
-
|
|
37
|
+
Use pi's built-in `/name` command when you want to set an exact name.
|
|
31
38
|
|
|
32
39
|
## Configuration
|
|
33
40
|
|
|
34
|
-
|
|
41
|
+
Default model:
|
|
42
|
+
|
|
43
|
+
```text
|
|
44
|
+
openai-codex/gpt-5.6-luna
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Use `/rename config` to choose another model or reset to the default.
|
|
48
|
+
|
|
49
|
+
To preserve existing behavior, names use ASCII when no language is configured. Set an output language with a BCP 47 tag, or use `auto` to follow latest user message language:
|
|
35
50
|
|
|
36
|
-
|
|
51
|
+
```bash
|
|
52
|
+
/rename config language <BCP-47-tag>
|
|
53
|
+
/rename config language auto
|
|
54
|
+
```
|
|
37
55
|
|
|
38
|
-
|
|
56
|
+
`auto` and non-`en` tags preserve Unicode letters and numbers. If rename model is unavailable, fallback uses latest user message and does not translate it.
|
|
39
57
|
|
|
40
58
|
You can also edit `$PI_CODING_AGENT_DIR/extensions/pi-rename.json` manually:
|
|
41
59
|
|
|
42
60
|
```json
|
|
43
61
|
{
|
|
44
|
-
"model": "openai-codex/gpt-5.6-luna"
|
|
62
|
+
"model": "openai-codex/gpt-5.6-luna",
|
|
63
|
+
"language": "auto"
|
|
45
64
|
}
|
|
46
65
|
```
|
|
47
66
|
|
|
48
|
-
|
|
67
|
+
Use `"language": "en"` for ASCII compatibility mode. Missing or invalid language values also fall back to `en`.
|
|
49
68
|
|
|
50
|
-
Herdr
|
|
51
|
-
|
|
52
|
-
The extension uses `HERDR_PANE_ID` to find the current Herdr pane. With one pane in the tab, it renames both the pane and tab. With sibling panes, it renames only the current pane.
|
|
69
|
+
## Herdr behavior
|
|
53
70
|
|
|
54
|
-
|
|
71
|
+
- Requires the `herdr` CLI.
|
|
72
|
+
- With one pane, renames both the pane and tab.
|
|
73
|
+
- In a split tab, renames only the current pane.
|
|
74
|
+
- Does not replace custom labels on startup or resume.
|
|
75
|
+
- Replaces default or temporary startup labels.
|
|
76
|
+
- Keeps the last name when pi exits.
|
|
55
77
|
|
|
56
|
-
|
|
78
|
+
For temporary launcher labels, set `HERDR_TEMPORARY_LABEL`:
|
|
57
79
|
|
|
58
80
|
```bash
|
|
59
81
|
HERDR_TEMPORARY_LABEL="my-project (pi)" pi
|
|
60
82
|
```
|
|
61
83
|
|
|
62
|
-
|
|
63
|
-
On quit, the target keeps the last session name.
|
|
84
|
+
Without it, only Herdr's default label is replaced.
|
|
64
85
|
|
|
65
|
-
|
|
86
|
+
Outside Herdr, only the pi session is renamed.
|
|
66
87
|
|
|
67
88
|
## Release notes
|
|
68
89
|
|
|
@@ -12,14 +12,20 @@ import type {
|
|
|
12
12
|
import { buildSessionContext } from "@earendil-works/pi-coding-agent"
|
|
13
13
|
import { pickRenameModel } from "./model-picker.js"
|
|
14
14
|
import {
|
|
15
|
-
|
|
15
|
+
DEFAULT_RENAME_LANGUAGE,
|
|
16
|
+
parseRenameLanguage,
|
|
17
|
+
type RenameLanguage,
|
|
18
|
+
} from "./language.js"
|
|
19
|
+
import {
|
|
20
|
+
deleteModelPreference,
|
|
16
21
|
formatAuthModelKey,
|
|
17
22
|
formatModelPreference,
|
|
18
23
|
formatRenameModelKey,
|
|
19
24
|
getAuthenticatedTextModelPreferences,
|
|
20
25
|
getRenameModelAuth,
|
|
21
|
-
|
|
26
|
+
resolveInitialRenameConfig,
|
|
22
27
|
saveModelPreference,
|
|
28
|
+
saveRenameLanguage,
|
|
23
29
|
type RenameModelConfig,
|
|
24
30
|
} from "./models.js"
|
|
25
31
|
import { isTemporaryHerdrLabel } from "./herdr-label.js"
|
|
@@ -32,6 +38,7 @@ interface SessionContextReader {
|
|
|
32
38
|
|
|
33
39
|
interface RenameState {
|
|
34
40
|
modelConfig: RenameModelConfig
|
|
41
|
+
language: RenameLanguage
|
|
35
42
|
}
|
|
36
43
|
|
|
37
44
|
const RENAME_SUBCOMMANDS: AutocompleteItem[] = [
|
|
@@ -55,6 +62,7 @@ const RENAME_SUBCOMMANDS: AutocompleteItem[] = [
|
|
|
55
62
|
function createRenameState(): RenameState {
|
|
56
63
|
return {
|
|
57
64
|
modelConfig: { kind: "missing" },
|
|
65
|
+
language: DEFAULT_RENAME_LANGUAGE,
|
|
58
66
|
}
|
|
59
67
|
}
|
|
60
68
|
|
|
@@ -241,7 +249,12 @@ async function runRenameCommand(
|
|
|
241
249
|
})
|
|
242
250
|
}
|
|
243
251
|
try {
|
|
244
|
-
const result = await generateRename(
|
|
252
|
+
const result = await generateRename(
|
|
253
|
+
ctx,
|
|
254
|
+
state.modelConfig,
|
|
255
|
+
context,
|
|
256
|
+
state.language,
|
|
257
|
+
)
|
|
245
258
|
if (!result) {
|
|
246
259
|
ctx.ui.notify("Could not generate a session name.", "error")
|
|
247
260
|
return
|
|
@@ -315,7 +328,7 @@ async function configureRenameModel(
|
|
|
315
328
|
|
|
316
329
|
try {
|
|
317
330
|
if (result.action === "default") {
|
|
318
|
-
|
|
331
|
+
deleteModelPreference()
|
|
319
332
|
state.modelConfig = { kind: "missing" }
|
|
320
333
|
ctx.ui.notify("Rename model reset to default.", "info")
|
|
321
334
|
return
|
|
@@ -334,6 +347,28 @@ async function configureRenameModel(
|
|
|
334
347
|
}
|
|
335
348
|
}
|
|
336
349
|
|
|
350
|
+
function configureRenameLanguage(
|
|
351
|
+
ctx: ExtensionContext,
|
|
352
|
+
state: RenameState,
|
|
353
|
+
value: string | undefined,
|
|
354
|
+
): void {
|
|
355
|
+
const language = parseRenameLanguage(value)
|
|
356
|
+
if (!language) {
|
|
357
|
+
ctx.ui.notify("Use /rename config language <auto|BCP-47>", "error")
|
|
358
|
+
return
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
try {
|
|
362
|
+
saveRenameLanguage(language)
|
|
363
|
+
state.language = language
|
|
364
|
+
ctx.ui.notify(`Rename language set to ${language}.`, "info")
|
|
365
|
+
} catch (error) {
|
|
366
|
+
const reason =
|
|
367
|
+
error instanceof SyntaxError ? "invalid JSON" : "write failed"
|
|
368
|
+
ctx.ui.notify(`Could not update rename config: ${reason}.`, "error")
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
337
372
|
async function notifyRenameStatus(
|
|
338
373
|
ctx: ExtensionContext,
|
|
339
374
|
state: RenameState,
|
|
@@ -365,6 +400,7 @@ async function notifyRenameStatus(
|
|
|
365
400
|
"pi-rename status",
|
|
366
401
|
selectedModelLine,
|
|
367
402
|
activeModelLine,
|
|
403
|
+
`language: ${state.language}`,
|
|
368
404
|
herdrLine,
|
|
369
405
|
contextLine,
|
|
370
406
|
].join("\n"),
|
|
@@ -377,20 +413,22 @@ function registerRenameCommand(pi: ExtensionAPI, state: RenameState): void {
|
|
|
377
413
|
description: "generate a session name",
|
|
378
414
|
getArgumentCompletions: getRenameArgumentCompletions,
|
|
379
415
|
handler: async (args, ctx) => {
|
|
380
|
-
const action = args.trim().split(/\s+/u)
|
|
416
|
+
const [action = "", ...actionArgs] = args.trim().split(/\s+/u)
|
|
417
|
+
const normalizedAction = action.toLowerCase()
|
|
381
418
|
|
|
382
|
-
if (!
|
|
419
|
+
if (!normalizedAction) {
|
|
383
420
|
await runRenameCommand(pi, ctx, state)
|
|
384
421
|
return
|
|
385
422
|
}
|
|
386
423
|
|
|
387
|
-
if (
|
|
424
|
+
if (normalizedAction === "help") {
|
|
388
425
|
ctx.ui.notify(
|
|
389
426
|
[
|
|
390
427
|
"pi-rename commands",
|
|
391
428
|
"/rename - generate and apply a session name",
|
|
392
429
|
"/rename status - show model and rename status",
|
|
393
430
|
"/rename config - choose the rename model",
|
|
431
|
+
"/rename config language <auto|BCP-47> - set name language",
|
|
394
432
|
"/rename help - show this help",
|
|
395
433
|
].join("\n"),
|
|
396
434
|
"info",
|
|
@@ -398,13 +436,24 @@ function registerRenameCommand(pi: ExtensionAPI, state: RenameState): void {
|
|
|
398
436
|
return
|
|
399
437
|
}
|
|
400
438
|
|
|
401
|
-
if (
|
|
439
|
+
if (normalizedAction === "status") {
|
|
402
440
|
await notifyRenameStatus(ctx, state)
|
|
403
441
|
return
|
|
404
442
|
}
|
|
405
443
|
|
|
406
|
-
if (
|
|
407
|
-
|
|
444
|
+
if (normalizedAction === "config") {
|
|
445
|
+
const [setting, value, extra] = actionArgs
|
|
446
|
+
if (!setting) {
|
|
447
|
+
await configureRenameModel(ctx, state)
|
|
448
|
+
return
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
if (setting.toLowerCase() === "language" && !extra) {
|
|
452
|
+
configureRenameLanguage(ctx, state, value)
|
|
453
|
+
return
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
ctx.ui.notify("Use /rename config language <auto|BCP-47>", "error")
|
|
408
457
|
return
|
|
409
458
|
}
|
|
410
459
|
|
|
@@ -419,7 +468,9 @@ export default function (pi: ExtensionAPI): void {
|
|
|
419
468
|
registerRenameCommand(pi, state)
|
|
420
469
|
|
|
421
470
|
pi.on("session_start", async () => {
|
|
422
|
-
|
|
471
|
+
const initialConfig = resolveInitialRenameConfig()
|
|
472
|
+
state.modelConfig = initialConfig.modelConfig
|
|
473
|
+
state.language = initialConfig.language
|
|
423
474
|
|
|
424
475
|
const sessionName = pi.getSessionName()?.trim()
|
|
425
476
|
if (!sessionName) return
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const DEFAULT_RENAME_LANGUAGE = "en"
|
|
2
|
+
export type RenameLanguage = string
|
|
3
|
+
|
|
4
|
+
export function parseRenameLanguage(
|
|
5
|
+
value: unknown,
|
|
6
|
+
): RenameLanguage | undefined {
|
|
7
|
+
if (typeof value !== "string") return undefined
|
|
8
|
+
|
|
9
|
+
const trimmed = value.trim()
|
|
10
|
+
if (trimmed.toLowerCase() === "auto") return "auto"
|
|
11
|
+
if (!trimmed) return undefined
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
return Intl.getCanonicalLocales(trimmed)[0]
|
|
15
|
+
} catch {
|
|
16
|
+
return undefined
|
|
17
|
+
}
|
|
18
|
+
}
|