@herbertgao/pi-extensions 2026.9.15 → 2026.9.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. package/README.md +5 -0
  2. package/THIRD_PARTY_NOTICES.md +26 -0
  3. package/node_modules/@herbertgao/pi-cc-extensions/package.json +1 -1
  4. package/node_modules/@herbertgao/sol-pi/package.json +1 -1
  5. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/extension.ts +11 -53
  6. package/node_modules/@narumitw/pi-btw/dist/index.ts +12 -6
  7. package/node_modules/@narumitw/pi-btw/dist/index.ts.map +3 -3
  8. package/node_modules/@narumitw/pi-btw/package.json +4 -4
  9. package/node_modules/@narumitw/pi-btw/src/main-tree-picker.ts +2 -0
  10. package/node_modules/@narumitw/pi-btw/src/side-thread.ts +16 -4
  11. package/node_modules/pi-lens/CHANGELOG.md +498 -0
  12. package/node_modules/pi-lens/README.md +45 -2
  13. package/node_modules/pi-lens/dist/clients/actionable-warnings.js +23 -7
  14. package/node_modules/pi-lens/dist/clients/advisory-provenance.js +187 -51
  15. package/node_modules/pi-lens/dist/clients/cache-manager.js +64 -5
  16. package/node_modules/pi-lens/dist/clients/child-unref.js +17 -8
  17. package/node_modules/pi-lens/dist/clients/config-diagnostic-codes.js +2 -0
  18. package/node_modules/pi-lens/dist/clients/config-locations.js +237 -9
  19. package/node_modules/pi-lens/dist/clients/config-resolve.js +7 -1
  20. package/node_modules/pi-lens/dist/clients/degradation-ledger.js +33 -3
  21. package/node_modules/pi-lens/dist/clients/dependency-checker.js +87 -64
  22. package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +39 -3
  23. package/node_modules/pi-lens/dist/clients/dispatch/finding-policy.js +118 -1
  24. package/node_modules/pi-lens/dist/clients/dispatch/indent-detect.js +8 -2
  25. package/node_modules/pi-lens/dist/clients/dispatch/inline-suppressions.js +23 -4
  26. package/node_modules/pi-lens/dist/clients/dispatch/rule-ignores.js +14 -7
  27. package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +26 -28
  28. package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +38 -25
  29. package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +32 -49
  30. package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +16 -14
  31. package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +25 -7
  32. package/node_modules/pi-lens/dist/clients/dispatch/runners/dart-analyze.js +28 -47
  33. package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +11 -4
  34. package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +27 -22
  35. package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +31 -46
  36. package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +29 -46
  37. package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +91 -11
  38. package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +16 -2
  39. package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +38 -23
  40. package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +27 -15
  41. package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +17 -8
  42. package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +31 -21
  43. package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +34 -60
  44. package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +6 -5
  45. package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +12 -5
  46. package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +2 -1
  47. package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +22 -6
  48. package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +39 -16
  49. package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +1 -1
  50. package/node_modules/pi-lens/dist/clients/dispatch/runners/rubocop.js +27 -18
  51. package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +18 -19
  52. package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +6 -1
  53. package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +6 -2
  54. package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +10 -3
  55. package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +11 -2
  56. package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +10 -2
  57. package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +11 -2
  58. package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +12 -6
  59. package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +30 -15
  60. package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +23 -0
  61. package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +8 -2
  62. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +11 -1
  63. package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +15 -3
  64. package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +12 -2
  65. package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +27 -39
  66. package/node_modules/pi-lens/dist/clients/dispatch/suppress-writer.js +13 -3
  67. package/node_modules/pi-lens/dist/clients/effective-config.js +3 -1
  68. package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +42 -11
  69. package/node_modules/pi-lens/dist/clients/formatters.js +49 -11
  70. package/node_modules/pi-lens/dist/clients/git-guard.js +247 -34
  71. package/node_modules/pi-lens/dist/clients/gradle-ktfmt-style.js +121 -25
  72. package/node_modules/pi-lens/dist/clients/inline-blocker-dispositions.js +186 -0
  73. package/node_modules/pi-lens/dist/clients/install-diagnostics.js +19 -6
  74. package/node_modules/pi-lens/dist/clients/installer/index.js +281 -32
  75. package/node_modules/pi-lens/dist/clients/jscpd-client.js +8 -0
  76. package/node_modules/pi-lens/dist/clients/latency-logger.js +8 -0
  77. package/node_modules/pi-lens/dist/clients/lens-config.js +66 -8
  78. package/node_modules/pi-lens/dist/clients/lsp/client.js +139 -11
  79. package/node_modules/pi-lens/dist/clients/lsp/config.js +9 -7
  80. package/node_modules/pi-lens/dist/clients/lsp/content-limits.js +41 -0
  81. package/node_modules/pi-lens/dist/clients/lsp/index.js +1 -1
  82. package/node_modules/pi-lens/dist/clients/lsp/launch.js +23 -2
  83. package/node_modules/pi-lens/dist/clients/lsp/server.js +106 -25
  84. package/node_modules/pi-lens/dist/clients/lsp/sync-kind.js +14 -0
  85. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +105 -16
  86. package/node_modules/pi-lens/dist/clients/mcp/ipc.js +232 -44
  87. package/node_modules/pi-lens/dist/clients/mcp/review.js +53 -7
  88. package/node_modules/pi-lens/dist/clients/opengrep-client.js +11 -6
  89. package/node_modules/pi-lens/dist/clients/pipeline.js +121 -66
  90. package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +21 -3
  91. package/node_modules/pi-lens/dist/clients/project-lens-config.js +11 -3
  92. package/node_modules/pi-lens/dist/clients/review-graph/builder.js +34 -26
  93. package/node_modules/pi-lens/dist/clients/review-graph/git-identity.js +16 -10
  94. package/node_modules/pi-lens/dist/clients/ruff-client.js +31 -4
  95. package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +38 -4
  96. package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +16 -5
  97. package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +27 -12
  98. package/node_modules/pi-lens/dist/clients/runtime-turn.js +447 -280
  99. package/node_modules/pi-lens/dist/clients/safe-spawn.js +256 -65
  100. package/node_modules/pi-lens/dist/clients/spawn-output-cap.js +84 -1
  101. package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +119 -58
  102. package/node_modules/pi-lens/dist/clients/turn-end/lane.js +51 -0
  103. package/node_modules/pi-lens/dist/clients/turn-end/lanes/govulncheck.js +112 -0
  104. package/node_modules/pi-lens/dist/clients/turn-end/lanes/secrets.js +204 -0
  105. package/node_modules/pi-lens/dist/clients/warm-attach.js +59 -0
  106. package/node_modules/pi-lens/dist/clients/widget-state.js +145 -14
  107. package/node_modules/pi-lens/dist/clients/workspace-topology.js +57 -3
  108. package/node_modules/pi-lens/dist/clients/zizmor-config.js +26 -13
  109. package/node_modules/pi-lens/dist/index.js +5695 -3733
  110. package/node_modules/pi-lens/dist/mcp/analyze-cli.js +4 -0
  111. package/node_modules/pi-lens/dist/mcp/server.js +33 -21
  112. package/node_modules/pi-lens/dist/scripts/lib/web-tree-sitter-dir.mjs +123 -0
  113. package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +43 -16
  114. package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +118 -7
  115. package/node_modules/pi-lens/docs/adr/0001-stale-advisory-live-arm.md +29 -0
  116. package/node_modules/pi-lens/docs/adr/0002-workspace-hash-rendezvous.md +30 -0
  117. package/node_modules/pi-lens/docs/adr/0003-git-guard-latch-writer.md +203 -0
  118. package/node_modules/pi-lens/docs/adr/0004-disposition-policy-seam.md +38 -0
  119. package/node_modules/pi-lens/docs/adr/0005-tool-availability-enforcement-seam.md +29 -0
  120. package/node_modules/pi-lens/docs/adr/0006-derived-state-benchmark-first.md +31 -0
  121. package/node_modules/pi-lens/docs/adr/0007-end-to-end-witness-per-seam-slice.md +38 -0
  122. package/node_modules/pi-lens/docs/adr/0008-turn-end-lane-interface.md +165 -0
  123. package/node_modules/pi-lens/docs/adr/0009-reported-path-attribution.md +114 -0
  124. package/node_modules/pi-lens/docs/adr/README.md +26 -0
  125. package/node_modules/pi-lens/docs/agent-tools.md +18 -1
  126. package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +4 -3
  127. package/node_modules/pi-lens/docs/configuration.md +55 -1
  128. package/node_modules/pi-lens/docs/engineering-principles.md +202 -0
  129. package/node_modules/pi-lens/docs/environment-variables.md +61 -4
  130. package/node_modules/pi-lens/docs/features.md +2 -2
  131. package/node_modules/pi-lens/docs/globalconfig.md +6 -1
  132. package/node_modules/pi-lens/docs/language-coverage.md +17 -0
  133. package/node_modules/pi-lens/docs/lsp-capability-matrix.md +98 -31
  134. package/node_modules/pi-lens/docs/pi-lens-fixer.md +57 -3
  135. package/node_modules/pi-lens/docs/pi-lens-investigator.md +9 -0
  136. package/node_modules/pi-lens/docs/pi-lens-reviewer.md +16 -0
  137. package/node_modules/pi-lens/docs/pi-lens-subagent.md +9 -0
  138. package/node_modules/pi-lens/docs/public-api-stability.md +1 -0
  139. package/node_modules/pi-lens/docs/release-qa-baseline.md +2 -0
  140. package/node_modules/pi-lens/docs/servercapabilities.md +21 -11
  141. package/node_modules/pi-lens/docs/settings.md +12 -3
  142. package/node_modules/pi-lens/docs/subagent-compat.md +1 -1
  143. package/node_modules/pi-lens/package.json +5 -3
  144. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-assert-tuple-test.yml +13 -0
  145. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-boolean-in-except-test.yml +26 -0
  146. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-http-headers-bracket-access-test.yml +10 -0
  147. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/unchecked-numeric-parse-python-test.yml +18 -0
  148. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/unchecked-throwing-call-python-test.yml +4 -3
  149. package/node_modules/pi-lens/rules/ast-grep-rules/rules/go-no-fmt-println.yml +2 -2
  150. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-assert-tuple.yml +23 -13
  151. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-boolean-in-except.yml +7 -3
  152. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-console-except-error-js.yml +2 -2
  153. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-console-except-error.yml +2 -2
  154. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-http-headers-bracket-access.yml +12 -7
  155. package/node_modules/pi-lens/rules/ast-grep-rules/rules/unchecked-numeric-parse-python.yml +44 -0
  156. package/node_modules/pi-lens/rules/ast-grep-rules/rules/unchecked-throwing-call-python.yml +5 -3
  157. package/node_modules/pi-lens/rules/tree-sitter-queries/typescript/console-statement.yml +2 -2
  158. package/node_modules/pi-lens/scripts/install-selftest.mjs +21 -17
  159. package/node_modules/pi-lens/scripts/lib/web-tree-sitter-dir.mjs +123 -0
  160. package/node_modules/pi-mcp-adapter/CHANGELOG.md +29 -0
  161. package/node_modules/pi-mcp-adapter/OAUTH.md +369 -0
  162. package/node_modules/pi-mcp-adapter/README.md +12 -5
  163. package/node_modules/pi-mcp-adapter/config.ts +31 -8
  164. package/node_modules/pi-mcp-adapter/direct-tool-surface.ts +1 -1
  165. package/node_modules/pi-mcp-adapter/dist/config.js +33 -8
  166. package/node_modules/pi-mcp-adapter/dist/config.js.map +1 -1
  167. package/node_modules/pi-mcp-adapter/dist/json-schema-validator.js +15 -2
  168. package/node_modules/pi-mcp-adapter/dist/json-schema-validator.js.map +1 -1
  169. package/node_modules/pi-mcp-adapter/dist/mcp-auth.d.ts +2 -0
  170. package/node_modules/pi-mcp-adapter/dist/mcp-auth.js +27 -2
  171. package/node_modules/pi-mcp-adapter/dist/mcp-auth.js.map +1 -1
  172. package/node_modules/pi-mcp-adapter/dist/metadata-cache.js +1 -1
  173. package/node_modules/pi-mcp-adapter/dist/metadata-cache.js.map +1 -1
  174. package/node_modules/pi-mcp-adapter/dist/server-manager.js +6 -4
  175. package/node_modules/pi-mcp-adapter/dist/server-manager.js.map +1 -1
  176. package/node_modules/pi-mcp-adapter/dist/types.d.ts +2 -2
  177. package/node_modules/pi-mcp-adapter/dist/utils.d.ts +2 -0
  178. package/node_modules/pi-mcp-adapter/dist/utils.js +10 -3
  179. package/node_modules/pi-mcp-adapter/dist/utils.js.map +1 -1
  180. package/node_modules/pi-mcp-adapter/index.ts +37 -20
  181. package/node_modules/pi-mcp-adapter/init.ts +14 -15
  182. package/node_modules/pi-mcp-adapter/json-schema-validator.ts +16 -2
  183. package/node_modules/pi-mcp-adapter/mcp-auth.ts +27 -2
  184. package/node_modules/pi-mcp-adapter/metadata-cache.ts +1 -1
  185. package/node_modules/pi-mcp-adapter/package.json +3 -2
  186. package/node_modules/pi-mcp-adapter/proxy-modes.ts +1 -1
  187. package/node_modules/pi-mcp-adapter/server-manager.ts +6 -3
  188. package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +99 -6
  189. package/node_modules/pi-mcp-adapter/types.ts +2 -2
  190. package/node_modules/pi-mcp-adapter/ui-session.ts +60 -27
  191. package/node_modules/pi-mcp-adapter/utils.ts +11 -3
  192. package/node_modules/pi-next-cue/.github/workflows/publish.yml +20 -0
  193. package/node_modules/pi-next-cue/LICENSE +21 -0
  194. package/node_modules/pi-next-cue/README.md +81 -0
  195. package/node_modules/pi-next-cue/index.ts +358 -0
  196. package/node_modules/pi-next-cue/package.json +28 -0
  197. package/package.json +9 -6
package/README.md CHANGED
@@ -29,6 +29,7 @@ The package bundles 6 active `@herbertgao/*` child packages—`pi-bark`, `pi-cc-
29
29
  - `pi-mcp-adapter@2.31.0`
30
30
  - `pi-typesafe@0.7.1`
31
31
  - `pi-multi-account@1.23.2`
32
+ - `pi-next-cue@1.0.7`
32
33
  - `pi-footer@0.5.1`
33
34
  - `pi-jev-auto-mode@0.5.0`
34
35
  - `pi-lens@4.2.1`
@@ -49,6 +50,10 @@ Pi loads their extensions and skills through `node_modules/` paths inside one pa
49
50
 
50
51
  `pi-stash` is no longer bundled: `/btw` already preserves the main editor draft while handling side questions outside the main conversation. Prior `@herbertgao/pi-stash` releases remain available but are no longer maintained here.
51
52
 
53
+ ### Next-cue suggestions
54
+
55
+ `pi-next-cue@1.0.7` predicts a short next prompt after each completed agent turn. In the empty editor, `Tab` fills the suggestion and `Enter` sends it. Each settled turn can make one extra model request using recent conversation text, recent tool names/results, and the configured active or explicitly selected model. It is TUI-only and wraps the prompt editor, so do not enable another custom-editor extension that also owns the editor slot.
56
+
52
57
  If `pi-footer` was installed separately before upgrading to an aggregate release that includes it, remove the standalone source shown by `pi list` so only the bundled copy loads. For the pinned standalone install used while preparing this integration:
53
58
 
54
59
  ```bash
@@ -186,3 +186,29 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
186
186
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
187
187
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
188
188
  THE SOFTWARE.
189
+
190
+ ## `pi-next-cue`
191
+
192
+ The aggregate bundles [`pi-next-cue`](https://github.com/ouzhenkun/pi-next-cue) version 1.0.7 under its original MIT license. The imported npm package corresponds to upstream commit [`015a595c6751d50889b3a6937ba4816dfe92adc1`](https://github.com/ouzhenkun/pi-next-cue/commit/015a595c6751d50889b3a6937ba4816dfe92adc1).
193
+
194
+ MIT License
195
+
196
+ Copyright (c) 2025 ouzhenkun
197
+
198
+ Permission is hereby granted, free of charge, to any person obtaining a copy
199
+ of this software and associated documentation files (the "Software"), to deal
200
+ in the Software without restriction, including without limitation the rights
201
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
202
+ copies of the Software, and to permit persons to whom the Software is
203
+ furnished to do so, subject to the following conditions:
204
+
205
+ The above copyright notice and this permission notice shall be included in
206
+ all copies or substantial portions of the Software.
207
+
208
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
209
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
210
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
211
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
212
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
213
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
214
+ THE SOFTWARE.
@@ -70,7 +70,7 @@
70
70
  "x-upstream": {
71
71
  "package": "pi-cc-extensions",
72
72
  "version": "0.8.71",
73
- "reviewedVersion": "0.9.2",
73
+ "reviewedVersion": "0.9.5",
74
74
  "repository": "https://github.com/minuque/pi-cc-extensions",
75
75
  "commit": "e43e0041b59f5d7f03be9b9d103a5f9e954e4c11"
76
76
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@herbertgao/sol-pi",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "Token-efficient context and tool extensions for Pi, maintained from NVlabs/SoL-Pi.",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -49,7 +49,6 @@ export type OnlineContextCompactOptions = {
49
49
  type PendingBoundary = { readonly toolCallId: string };
50
50
  type SelectedCompaction = { readonly decision: CompactionDecision };
51
51
  type CacheDebt = { readonly debtTokens: number; readonly repaymentTokens: number };
52
- type PendingContinuation = { readonly promise: Promise<void>; readonly resolve: () => void };
53
52
 
54
53
  const SUBAGENTS_MANAGER_KEY = Symbol.for("pi-subagents:manager");
55
54
 
@@ -197,10 +196,6 @@ function restoreCompactionThinking(pi: ExtensionAPI, override: CompactionThinkin
197
196
  }
198
197
  }
199
198
 
200
- function releaseParentContinuation(continuation: PendingContinuation | undefined): void {
201
- if (continuation) setTimeout(continuation.resolve, 0);
202
- }
203
-
204
199
  export function createOnlineContextCompactExtension(options: OnlineContextCompactOptions = {}): ExtensionFactory {
205
200
  const keepRecentTokens = resolveKeepRecentTokens(options.keepRecentTokens);
206
201
  const cacheWriteReadRatio = resolveCacheWriteReadRatio(options.cacheWriteReadRatio);
@@ -212,17 +207,10 @@ export function createOnlineContextCompactExtension(options: OnlineContextCompac
212
207
  let pendingBoundary: PendingBoundary | undefined;
213
208
  let selected: SelectedCompaction | undefined;
214
209
  let activeDebt: CacheDebt | undefined;
215
- let nextContinuation: PendingContinuation | undefined;
216
210
  let compactionInFlight = false;
217
211
  let compactionThinkingOverride: CompactionThinkingOverride | undefined;
218
212
 
219
- const releaseContinuation = (): void => {
220
- const continuation = nextContinuation;
221
- nextContinuation = undefined;
222
- continuation?.resolve();
223
- };
224
213
  const restore = (context: ExtensionContext): void => {
225
- releaseContinuation();
226
214
  state = restoreOnlineState(context.sessionManager.getBranch());
227
215
  restored = true;
228
216
  observedMessages = buildSessionContext(
@@ -358,21 +346,13 @@ export function createOnlineContextCompactExtension(options: OnlineContextCompac
358
346
  });
359
347
 
360
348
  pi.on("agent_settled", async (_event, context) => {
361
- // sendMessage() starts a turn without returning its promise. Capture the
362
- // child settlement so print/JSON mode cannot dispose while it is running.
363
- const parentContinuation = nextContinuation;
364
- nextContinuation = undefined;
365
349
  const pending = selected;
366
350
  selected = undefined;
367
351
  if (!context.isIdle()) {
368
352
  selected = pending;
369
- nextContinuation = parentContinuation;
370
- return;
371
- }
372
- if (!pending || hasRunningSubagents()) {
373
- releaseParentContinuation(parentContinuation);
374
353
  return;
375
354
  }
355
+ if (!pending || hasRunningSubagents()) return;
376
356
 
377
357
  activeDebt = {
378
358
  debtTokens: pending.decision.writeTokens * (pending.decision.incrementalCacheCostRatio ?? 0),
@@ -428,43 +408,22 @@ export function createOnlineContextCompactExtension(options: OnlineContextCompac
428
408
  }
429
409
 
430
410
  if (compacted) {
431
- let resolveContinuation!: () => void;
432
- const continuation: PendingContinuation = {
433
- promise: new Promise<void>((resolve) => {
434
- resolveContinuation = resolve;
435
- }),
436
- resolve: () => resolveContinuation(),
437
- };
438
- nextContinuation = continuation;
439
- try {
440
- pi.sendMessage(
441
- {
442
- customType: "sol-pi-online-context-compact",
443
- content: POST_COMPACTION_PLAN_REMINDER,
444
- display: false,
445
- },
446
- { triggerTurn: true },
447
- );
448
- } catch (error) {
449
- if (nextContinuation === continuation) nextContinuation = undefined;
450
- continuation.resolve();
451
- throw error;
452
- }
453
- // triggerTurn starts on the next event-loop turn; checking immediately is racy.
454
- await new Promise<void>((resolve) => setTimeout(resolve, 0));
455
- if (context.isIdle() && nextContinuation === continuation) {
456
- nextContinuation = undefined;
457
- continuation.resolve();
458
- throw new Error("Online context compact continuation did not start");
459
- }
460
- await continuation.promise;
411
+ // Pi >=0.87 defers this turn until agent_settled handlers finish and
412
+ // awaits it before prompt() resolves, so print/JSON mode stays alive.
413
+ pi.sendMessage(
414
+ {
415
+ customType: "sol-pi-online-context-compact",
416
+ content: POST_COMPACTION_PLAN_REMINDER,
417
+ display: false,
418
+ },
419
+ { triggerTurn: true },
420
+ );
461
421
  }
462
422
  } finally {
463
423
  restoreCompactionThinking(pi, compactionThinkingOverride);
464
424
  compactionThinkingOverride = undefined;
465
425
  compactionInFlight = false;
466
426
  activeDebt = undefined;
467
- releaseParentContinuation(parentContinuation);
468
427
  }
469
428
  });
470
429
 
@@ -487,7 +446,6 @@ export function createOnlineContextCompactExtension(options: OnlineContextCompac
487
446
  pi.on("session_shutdown", () => {
488
447
  restoreCompactionThinking(pi, compactionThinkingOverride);
489
448
  compactionThinkingOverride = undefined;
490
- releaseContinuation();
491
449
  pendingBoundary = undefined;
492
450
  selected = undefined;
493
451
  activeDebt = undefined;
@@ -746,16 +746,17 @@ import {
746
746
  } from "@earendil-works/pi-tui";
747
747
 
748
748
  // src/settings.ts
749
- import { randomUUID } from "node:crypto";
749
+ import { randomUUID as randomUUID2 } from "node:crypto";
750
750
  import { constants } from "node:fs";
751
751
  import { mkdir, open, rename, rm, writeFile } from "node:fs/promises";
752
752
  import { basename, dirname, join } from "node:path";
753
753
  import { getAgentDir } from "@earendil-works/pi-coding-agent";
754
754
 
755
755
  // src/side-thread.ts
756
+ import { randomUUID } from "node:crypto";
756
757
  var BTW_THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh", "max"];
757
758
  function createSideThread(conversationContext) {
758
- return { conversationContext, turns: [] };
759
+ return { conversationContext, turns: [], routingSessionId: randomUUID() };
759
760
  }
760
761
  function buildSideThreadMessages(thread, question) {
761
762
  const answeredTurns = thread.turns.filter(
@@ -791,7 +792,7 @@ async function completeSideThreadTurn({
791
792
  { systemPrompt: SYSTEM_PROMPT, messages: buildSideThreadMessages(thread, question) },
792
793
  buildStreamOptions(
793
794
  auth,
794
- { thinkingLevel, signal, model, sessionId },
795
+ { thinkingLevel, signal, model, sessionId, routingSessionId: thread.routingSessionId },
795
796
  completeSimple.appliesRequestHeaderTransforms === true
796
797
  )
797
798
  );
@@ -854,13 +855,16 @@ function mergeSessionHeaders(authHeaders, sessionHeaders) {
854
855
  if (!sessionHeaders && !authHeaders) return void 0;
855
856
  return { ...sessionHeaders, ...authHeaders };
856
857
  }
857
- function buildStreamOptions(auth, { thinkingLevel, signal, model, sessionId }, applyRequestHeaderTransforms) {
858
+ function buildStreamOptions(auth, { thinkingLevel, signal, model, sessionId, routingSessionId }, applyRequestHeaderTransforms) {
858
859
  const sessionHeaders = model ? getOpencodeSessionHeaders(model, sessionId) : void 0;
859
860
  const options = {
860
861
  apiKey: auth?.apiKey,
861
862
  headers: applyRequestHeaderTransforms ? auth?.headers : mergeSessionHeaders(auth?.headers, sessionHeaders),
862
863
  env: auth?.env,
863
- signal
864
+ signal,
865
+ // Pi documents sessionId as optional, but providers use it for request routing and
866
+ // some provider overrides require it. Pi core also mints a fresh ID for one-off requests.
867
+ sessionId: routingSessionId
864
868
  };
865
869
  if (applyRequestHeaderTransforms && sessionHeaders) {
866
870
  options.transformHeaders = (headers) => mergeSessionHeaders(headers, sessionHeaders) ?? {};
@@ -1059,7 +1063,7 @@ async function publishSettings(settingsPath, document, signal, beforeRename) {
1059
1063
  const directory = dirname(settingsPath);
1060
1064
  await mkdir(directory, { recursive: true });
1061
1065
  signal?.throwIfAborted();
1062
- const temporaryPath = join(directory, `.${basename(settingsPath)}.${process.pid}.${randomUUID()}.tmp`);
1066
+ const temporaryPath = join(directory, `.${basename(settingsPath)}.${process.pid}.${randomUUID2()}.tmp`);
1063
1067
  try {
1064
1068
  await writeFile(temporaryPath, contents, {
1065
1069
  encoding: "utf8",
@@ -3138,6 +3142,8 @@ function sanitizeEntryForDisplay(entry) {
3138
3142
  return { ...entry, thinkingLevel: sanitizeSingleLine(entry.thinkingLevel) };
3139
3143
  case "custom":
3140
3144
  return { ...entry, customType: sanitizeSingleLine(entry.customType) };
3145
+ case "context_edit":
3146
+ return { ...entry, targetId: sanitizeSingleLine(entry.targetId) };
3141
3147
  case "label":
3142
3148
  return {
3143
3149
  ...entry,