@herbertgao/pi-extensions 2026.9.2 → 2026.9.3

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 (221) hide show
  1. package/README.md +3 -2
  2. package/THIRD_PARTY_NOTICES.md +24 -0
  3. package/node_modules/@herbertgao/sol-pi/LICENSE +19 -0
  4. package/node_modules/@herbertgao/sol-pi/README.md +159 -0
  5. package/node_modules/@herbertgao/sol-pi/SECURITY.md +26 -0
  6. package/node_modules/@herbertgao/sol-pi/THIRD_PARTY_NOTICES.md +19 -0
  7. package/node_modules/@herbertgao/sol-pi/agents-install.md +150 -0
  8. package/node_modules/@herbertgao/sol-pi/assets/sol-pi-hero.png +0 -0
  9. package/node_modules/@herbertgao/sol-pi/docs/compatibility.md +69 -0
  10. package/node_modules/@herbertgao/sol-pi/docs/configuration.md +75 -0
  11. package/node_modules/@herbertgao/sol-pi/package.json +76 -0
  12. package/node_modules/@herbertgao/sol-pi/scripts/check-pi-compat.mjs +32 -0
  13. package/node_modules/@herbertgao/sol-pi/scripts/check-sol-pi-config.mjs +120 -0
  14. package/node_modules/@herbertgao/sol-pi/sol-pi.example.json +10 -0
  15. package/node_modules/@herbertgao/sol-pi/src/sol-pi/config.ts +135 -0
  16. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/file-queue.ts +74 -0
  17. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/index.ts +185 -0
  18. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/then-run.ts +128 -0
  19. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/archive.ts +53 -0
  20. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/candidate.ts +101 -0
  21. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/config.ts +71 -0
  22. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/index.ts +220 -0
  23. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/journal.ts +25 -0
  24. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/provider.ts +164 -0
  25. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/receipt.ts +177 -0
  26. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/observation-pack/index.ts +227 -0
  27. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/observation-pack/ledger.ts +20 -0
  28. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/observation-pack/observation.ts +252 -0
  29. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/economics.ts +237 -0
  30. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/extension.ts +455 -0
  31. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/index.ts +49 -0
  32. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/plan.ts +79 -0
  33. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/state.ts +208 -0
  34. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/tools.ts +100 -0
  35. package/node_modules/@herbertgao/sol-pi/src/sol-pi/index.ts +42 -0
  36. package/node_modules/@herbertgao/sol-pi/src/sol-pi/runtime-paths.ts +17 -0
  37. package/node_modules/@herbertgao/sol-pi/src/sol-pi/tui.ts +71 -0
  38. package/node_modules/@narumitw/pi-btw/dist/index.ts +12 -2
  39. package/node_modules/@narumitw/pi-btw/dist/index.ts.map +2 -2
  40. package/node_modules/@narumitw/pi-btw/package.json +1 -1
  41. package/node_modules/@narumitw/pi-btw/src/btw.ts +13 -2
  42. package/node_modules/pi-lens/CHANGELOG.md +176 -0
  43. package/node_modules/pi-lens/README.md +13 -8
  44. package/node_modules/pi-lens/config/dependency-cruiser-eager-allowlist.json +3 -1
  45. package/node_modules/pi-lens/dist/clients/analysed-root.js +1 -0
  46. package/node_modules/pi-lens/dist/clients/ast-grep-tool-logger.js +1 -1
  47. package/node_modules/pi-lens/dist/clients/biome-client.js +13 -2
  48. package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +2 -0
  49. package/node_modules/pi-lens/dist/clients/cache-observability.js +122 -1
  50. package/node_modules/pi-lens/dist/clients/complexity-client.js +5 -0
  51. package/node_modules/pi-lens/dist/clients/config-diagnostic-codes.js +2 -0
  52. package/node_modules/pi-lens/dist/clients/config-resolve.js +6 -3
  53. package/node_modules/pi-lens/dist/clients/config-schema.js +17 -0
  54. package/node_modules/pi-lens/dist/clients/config-warn.js +2 -2
  55. package/node_modules/pi-lens/dist/clients/dead-code-client.js +8 -1
  56. package/node_modules/pi-lens/dist/clients/dependency-checker.js +5 -1
  57. package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +38 -15
  58. package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +1 -1
  59. package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +5 -1
  60. package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +2 -1
  61. package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +2 -3
  62. package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +4 -3
  63. package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +2 -1
  64. package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +2 -1
  65. package/node_modules/pi-lens/dist/clients/dispatch/runners/dart-analyze.js +2 -1
  66. package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +2 -1
  67. package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +2 -1
  68. package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +2 -1
  69. package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +2 -1
  70. package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +2 -1
  71. package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +2 -1
  72. package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +2 -1
  73. package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +2 -1
  74. package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +2 -1
  75. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +3 -1
  76. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +2 -1
  77. package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +2 -1
  78. package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +2 -1
  79. package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +2 -1
  80. package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +19 -1
  81. package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +3 -2
  82. package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +2 -1
  83. package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +2 -1
  84. package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +2 -1
  85. package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +2 -1
  86. package/node_modules/pi-lens/dist/clients/dispatch/runners/prisma-validate.js +2 -1
  87. package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +12 -12
  88. package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +2 -1
  89. package/node_modules/pi-lens/dist/clients/dispatch/runners/rubocop.js +2 -1
  90. package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +2 -2
  91. package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +12 -11
  92. package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +2 -1
  93. package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +2 -1
  94. package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +2 -2
  95. package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.js +2 -1
  96. package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +3 -2
  97. package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +3 -2
  98. package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +2 -1
  99. package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +2 -1
  100. package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +2 -1
  101. package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +2 -1
  102. package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +2 -1
  103. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +5 -0
  104. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +2 -2
  105. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +8 -2
  106. package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +2 -1
  107. package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +4 -3
  108. package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +2 -1
  109. package/node_modules/pi-lens/dist/clients/effective-config.js +12 -2
  110. package/node_modules/pi-lens/dist/clients/extension-log.js +2 -0
  111. package/node_modules/pi-lens/dist/clients/file-role.js +18 -1
  112. package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +4 -0
  113. package/node_modules/pi-lens/dist/clients/formatters.js +54 -188
  114. package/node_modules/pi-lens/dist/clients/generation-guard.js +4 -0
  115. package/node_modules/pi-lens/dist/clients/gitleaks-client.js +42 -6
  116. package/node_modules/pi-lens/dist/clients/govulncheck-client.js +48 -7
  117. package/node_modules/pi-lens/dist/clients/installer/index.js +196 -52
  118. package/node_modules/pi-lens/dist/clients/jscpd-client.js +9 -1
  119. package/node_modules/pi-lens/dist/clients/knip-client.js +9 -2
  120. package/node_modules/pi-lens/dist/clients/language-profile.js +12 -2
  121. package/node_modules/pi-lens/dist/clients/latency-logger.js +2 -0
  122. package/node_modules/pi-lens/dist/clients/lens-config.js +4 -0
  123. package/node_modules/pi-lens/dist/clients/lsp/config.js +36 -7
  124. package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +24 -1
  125. package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +78 -0
  126. package/node_modules/pi-lens/dist/clients/lsp/index.js +281 -45
  127. package/node_modules/pi-lens/dist/clients/lsp/server.js +62 -15
  128. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +37 -4
  129. package/node_modules/pi-lens/dist/clients/mcp/analyze.js +3 -0
  130. package/node_modules/pi-lens/dist/clients/mcp/session.js +2 -0
  131. package/node_modules/pi-lens/dist/clients/opengrep-client.js +2 -0
  132. package/node_modules/pi-lens/dist/clients/package-manager.js +2 -1
  133. package/node_modules/pi-lens/dist/clients/php-cs-fixer-config.js +8 -3
  134. package/node_modules/pi-lens/dist/clients/pipeline.js +3 -2
  135. package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +38 -10
  136. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +10 -9
  137. package/node_modules/pi-lens/dist/clients/project-lens-config.js +3 -0
  138. package/node_modules/pi-lens/dist/clients/read-guard-logger.js +2 -0
  139. package/node_modules/pi-lens/dist/clients/review-graph-logger.js +2 -0
  140. package/node_modules/pi-lens/dist/clients/ruff-client.js +18 -9
  141. package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +9 -0
  142. package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +5 -0
  143. package/node_modules/pi-lens/dist/clients/runtime-session.js +13 -4
  144. package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +4 -1
  145. package/node_modules/pi-lens/dist/clients/runtime-turn.js +48 -1
  146. package/node_modules/pi-lens/dist/clients/security-scan-client.js +2 -2
  147. package/node_modules/pi-lens/dist/clients/session-event-guard.js +69 -1
  148. package/node_modules/pi-lens/dist/clients/sg-runner.js +2 -1
  149. package/node_modules/pi-lens/dist/clients/situational-tool-telemetry.js +108 -0
  150. package/node_modules/pi-lens/dist/clients/test-runner-client.js +291 -76
  151. package/node_modules/pi-lens/dist/clients/tool-config.js +199 -0
  152. package/node_modules/pi-lens/dist/clients/tool-cwd.js +299 -0
  153. package/node_modules/pi-lens/dist/clients/tool-probe.js +53 -0
  154. package/node_modules/pi-lens/dist/clients/tool-set-policy.js +42 -0
  155. package/node_modules/pi-lens/dist/clients/trivy-client.js +9 -1
  156. package/node_modules/pi-lens/dist/clients/turn-context.js +52 -0
  157. package/node_modules/pi-lens/dist/clients/widget-state.js +4 -3
  158. package/node_modules/pi-lens/dist/index.js +21969 -20005
  159. package/node_modules/pi-lens/dist/mcp/analyze-cli.js +3 -2
  160. package/node_modules/pi-lens/dist/mcp/server.js +135 -159
  161. package/node_modules/pi-lens/dist/tools/activate-tools.js +10 -7
  162. package/node_modules/pi-lens/dist/tools/ast-grep-outline.js +2 -13
  163. package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +8 -13
  164. package/node_modules/pi-lens/dist/tools/ast-grep-search.js +83 -39
  165. package/node_modules/pi-lens/dist/tools/effective-config.js +4 -3
  166. package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +1 -10
  167. package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +353 -85
  168. package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +21 -110
  169. package/node_modules/pi-lens/dist/tools/lsp-navigation.js +20 -44
  170. package/node_modules/pi-lens/dist/tools/module-report.js +5 -9
  171. package/node_modules/pi-lens/dist/tools/project-report.js +9 -17
  172. package/node_modules/pi-lens/dist/tools/render-compact.js +280 -1
  173. package/node_modules/pi-lens/dist/tools/symbol-search.js +2 -2
  174. package/node_modules/pi-lens/docs/agent-guide.md +3 -4
  175. package/node_modules/pi-lens/docs/agent-tools.md +46 -22
  176. package/node_modules/pi-lens/docs/configuration.md +9 -0
  177. package/node_modules/pi-lens/docs/environment-variables.md +0 -5
  178. package/node_modules/pi-lens/docs/features.md +5 -5
  179. package/node_modules/pi-lens/docs/globalconfig.md +11 -1
  180. package/node_modules/pi-lens/docs/mcp.md +13 -1
  181. package/node_modules/pi-lens/docs/pi-lens-fixer.md +71 -0
  182. package/node_modules/pi-lens/docs/pi-lens-investigator.md +15 -0
  183. package/node_modules/pi-lens/docs/pi-lens-monitor.md +88 -0
  184. package/node_modules/pi-lens/docs/pi-lens-reviewer.md +35 -0
  185. package/node_modules/pi-lens/docs/pi-lens-subagent.md +12 -4
  186. package/node_modules/pi-lens/docs/public-api-stability.md +1 -0
  187. package/node_modules/pi-lens/docs/real-harness.md +46 -0
  188. package/node_modules/pi-lens/docs/release-qa-baseline.md +5 -1
  189. package/node_modules/pi-lens/docs/servercapabilities.md +1 -6
  190. package/node_modules/pi-lens/docs/settings.md +37 -2
  191. package/node_modules/pi-lens/docs/tools_improvement2.md +4 -4
  192. package/node_modules/pi-lens/docs/tree-sitter_rules_catalog.md +1 -1
  193. package/node_modules/pi-lens/docs/usage.md +13 -3
  194. package/node_modules/pi-lens/package.json +10 -1
  195. package/node_modules/pi-lens/rules/tree-sitter-queries/typescript/sql-injection.yml +7 -3
  196. package/node_modules/pi-lens/skills/pi-lens-ast-grep/SKILL.md +8 -6
  197. package/node_modules/pi-lens/skills/pi-lens-lsp-navigation/SKILL.md +19 -9
  198. package/node_modules/pi-web-access/CHANGELOG.md +29 -0
  199. package/node_modules/pi-web-access/README.md +33 -22
  200. package/node_modules/pi-web-access/abortable.ts +17 -0
  201. package/node_modules/pi-web-access/crawl4ai.ts +204 -0
  202. package/node_modules/pi-web-access/credential-source.ts +1 -0
  203. package/node_modules/pi-web-access/curator-page.ts +20 -2
  204. package/node_modules/pi-web-access/curator-run.ts +44 -0
  205. package/node_modules/pi-web-access/curator-server.ts +3 -1
  206. package/node_modules/pi-web-access/duckduckgo.ts +1 -1
  207. package/node_modules/pi-web-access/extract.ts +57 -12
  208. package/node_modules/pi-web-access/fetch-params.ts +1 -1
  209. package/node_modules/pi-web-access/gemini-search.ts +9 -5
  210. package/node_modules/pi-web-access/index.ts +25 -18
  211. package/node_modules/pi-web-access/openai-search.ts +35 -13
  212. package/node_modules/pi-web-access/package.json +2 -2
  213. package/node_modules/pi-web-access/page-query.ts +5 -2
  214. package/node_modules/pi-web-access/query-rewrite.ts +5 -2
  215. package/node_modules/pi-web-access/serpapi.ts +220 -0
  216. package/node_modules/pi-web-access/ssrf-protection.ts +5 -1
  217. package/node_modules/pi-web-access/storage.ts +10 -0
  218. package/node_modules/pi-web-access/summary-review.ts +34 -21
  219. package/node_modules/pi-web-access/utils.ts +6 -4
  220. package/package.json +7 -4
  221. package/node_modules/pi-lens/dist/tools/ast-dump.js +0 -103
@@ -1,5 +1,5 @@
1
- import { clampThinkingLevel, type ModelThinkingLevel, type ThinkingLevel } from "@earendil-works/pi-ai";
2
- import { complete, completeSimple, type Api, type Message, type Model } from "@earendil-works/pi-ai/compat";
1
+ import type { ModelThinkingLevel, ThinkingLevel } from "@earendil-works/pi-ai";
2
+ import type { complete, Api, Message, Model } from "@earendil-works/pi-ai/compat";
3
3
  import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
4
4
  import { findModelWithProviderRouting, loadEnabledModelPatterns, modelMatchesEnabledPatterns, splitThinkingSuffix, type SummaryThinkingLevel } from "./summary-model-scope.ts";
5
5
  import type { QueryResultData } from "./storage.ts";
@@ -204,8 +204,9 @@ function parseModelSelector(value: string): { provider: string; id: string; thin
204
204
  };
205
205
  }
206
206
 
207
- function resolveThinkingLevel(model: Model<Api>, requested?: SummaryThinkingLevel): ModelThinkingLevel | undefined {
207
+ async function resolveThinkingLevel(model: Model<Api>, requested?: SummaryThinkingLevel): Promise<ModelThinkingLevel | undefined> {
208
208
  if (!requested) return undefined;
209
+ const { clampThinkingLevel } = await import("@earendil-works/pi-ai");
209
210
  return clampThinkingLevel(model, requested as ModelThinkingLevel);
210
211
  }
211
212
 
@@ -295,22 +296,21 @@ export async function generateSummaryDraft(
295
296
  if (!ctx || !ctx.modelRegistry) {
296
297
  throw new Error("Summary generation context unavailable");
297
298
  }
299
+ if (signal?.aborted) throw new Error("Aborted");
298
300
 
299
301
  const registry = ctx.modelRegistry as SummaryModelRegistry;
300
302
  const customCompleteFn = completeFn !== undefined;
301
303
  const usesRegistryComplete = !customCompleteFn && typeof registry.complete === "function";
302
- completeFn ??= usesRegistryComplete ? registry.complete!.bind(registry) as CompleteFunction : complete;
304
+ let piAiCompat: typeof import("@earendil-works/pi-ai/compat") | undefined;
303
305
 
304
306
  const generationStartedAt = Date.now();
305
307
  const deadlineController = new AbortController();
306
308
  const deadlineMarker = Symbol("summary-generation-deadline");
307
309
  let deadlineTimer: ReturnType<typeof setTimeout> | undefined;
308
- let resolveDeadline!: () => void;
309
310
  const deadlinePromise = new Promise<typeof deadlineMarker>(resolve => {
310
- resolveDeadline = () => resolve(deadlineMarker);
311
311
  deadlineTimer = setTimeout(() => {
312
312
  deadlineController.abort();
313
- resolveDeadline();
313
+ resolve(deadlineMarker);
314
314
  }, deadlineMs);
315
315
  });
316
316
 
@@ -326,17 +326,24 @@ export async function generateSummaryDraft(
326
326
  ? AbortSignal.any([signal, deadlineController.signal])
327
327
  : deadlineController.signal;
328
328
 
329
+ function checkSummaryDeadline(): void {
330
+ if (signal?.aborted) throw new Error("Aborted");
331
+ // Imports or synchronous providers can finish before an overdue timer runs.
332
+ if (deadlineController.signal.aborted || Date.now() - generationStartedAt >= deadlineMs) {
333
+ deadlineController.abort();
334
+ throw deadlineMarker;
335
+ }
336
+ }
337
+
329
338
  async function raceSummaryOperation<T>(operation: Promise<T>): Promise<T> {
330
339
  // A provider may ignore AbortSignal and never settle; observe it before racing so
331
340
  // its eventual rejection cannot become an unhandled promise rejection.
332
341
  void operation.then(() => undefined, () => undefined);
342
+ checkSummaryDeadline();
333
343
  const contenders: Promise<unknown>[] = [operation, deadlinePromise];
334
344
  if (callerAbortPromise) contenders.push(callerAbortPromise);
335
345
  const result = await Promise.race(contenders);
336
- if (result === deadlineMarker) {
337
- if (signal?.aborted) throw new Error("Aborted");
338
- throw deadlineMarker;
339
- }
346
+ checkSummaryDeadline();
340
347
  return result as T;
341
348
  }
342
349
 
@@ -345,12 +352,14 @@ export async function generateSummaryDraft(
345
352
  const prompt = buildSummaryPrompt(results, feedback);
346
353
  let resolved: Awaited<ReturnType<typeof resolveSummaryModelCandidates>>;
347
354
  try {
355
+ checkSummaryDeadline();
356
+ if (!customCompleteFn && !usesRegistryComplete) {
357
+ piAiCompat = await raceSummaryOperation(import("@earendil-works/pi-ai/compat"));
358
+ }
359
+ completeFn ??= usesRegistryComplete ? registry.complete!.bind(registry) as CompleteFunction : piAiCompat!.complete;
348
360
  resolved = await raceSummaryOperation(resolveSummaryModelCandidates(ctx, modelOverride));
349
361
  } catch (err) {
350
- if (signal?.aborted) throw new Error("Aborted");
351
- if (err === deadlineMarker || deadlineController.signal.aborted) {
352
- return buildFallbackSummary(results, "summary-generation-timeout", Date.now() - generationStartedAt);
353
- }
362
+ checkSummaryDeadline();
354
363
  const message = err instanceof Error ? err.message : String(err);
355
364
  return buildFallbackSummary(results, `summary-model-settings-error: ${message}`, Date.now() - generationStartedAt);
356
365
  }
@@ -364,7 +373,7 @@ export async function generateSummaryDraft(
364
373
  content: [{ type: "text", text: prompt }],
365
374
  timestamp: Date.now(),
366
375
  };
367
- const requestedThinkingLevel = resolveThinkingLevel(model, thinkingLevel);
376
+ const requestedThinkingLevel = await raceSummaryOperation(resolveThinkingLevel(model, thinkingLevel));
368
377
  const enabledThinkingLevel = requestedThinkingLevel && requestedThinkingLevel !== "off"
369
378
  ? requestedThinkingLevel as ThinkingLevel
370
379
  : undefined;
@@ -374,8 +383,9 @@ export async function generateSummaryDraft(
374
383
  ...(requestedThinkingLevel ? { reasoning: requestedThinkingLevel } : {}),
375
384
  ...(enabledThinkingLevel ? { reasoningEffort: enabledThinkingLevel } : {}),
376
385
  };
386
+ checkSummaryDeadline();
377
387
  const completion = thinkingLevel !== undefined && !customCompleteFn && !usesRegistryComplete
378
- ? completeSimple(model, { messages: [userMessage] }, { apiKey, headers, signal: completionSignal, ...(enabledThinkingLevel ? { reasoning: enabledThinkingLevel } : {}) })
388
+ ? piAiCompat!.completeSimple(model, { messages: [userMessage] }, { apiKey, headers, signal: completionSignal, ...(enabledThinkingLevel ? { reasoning: enabledThinkingLevel } : {}) })
379
389
  : completeFn(model, { messages: [userMessage] }, completionOptions);
380
390
 
381
391
  const response = await raceSummaryOperation(Promise.resolve(completion));
@@ -408,10 +418,7 @@ export async function generateSummaryDraft(
408
418
  },
409
419
  };
410
420
  } catch (err) {
411
- if (signal?.aborted) throw new Error("Aborted");
412
- if (err === deadlineMarker || deadlineController.signal.aborted) {
413
- return buildFallbackSummary(results, "summary-generation-timeout", Date.now() - generationStartedAt);
414
- }
421
+ checkSummaryDeadline();
415
422
  if (isAbortError(err)) throw err;
416
423
  lastError = err instanceof Error ? err.message : String(err);
417
424
  }
@@ -422,6 +429,12 @@ export async function generateSummaryDraft(
422
429
  lastError ? `summary-model-unavailable: ${lastError}` : "summary-model-unavailable",
423
430
  Date.now() - generationStartedAt,
424
431
  );
432
+ } catch (err) {
433
+ if (signal?.aborted) throw new Error("Aborted");
434
+ if (err === deadlineMarker) {
435
+ return buildFallbackSummary(results, "summary-generation-timeout", Date.now() - generationStartedAt);
436
+ }
437
+ throw err;
425
438
  } finally {
426
439
  if (deadlineTimer) clearTimeout(deadlineTimer);
427
440
  if (signal && callerAbortListener) signal.removeEventListener("abort", callerAbortListener);
@@ -22,7 +22,7 @@ export function getWebSearchConfigDir(): string {
22
22
  if (existsSync(join(legacyDir, "web-search.json"))) return cachedWebSearchConfigDir = legacyDir;
23
23
  return cachedWebSearchConfigDir = xdgDir;
24
24
  }
25
- return cachedWebSearchConfigDir = join(homedir(), ".pi");
25
+ return cachedWebSearchConfigDir = join(homedir(), ".pi", "agent");
26
26
  }
27
27
 
28
28
  export function getWebSearchConfigPath(): string {
@@ -208,7 +208,7 @@ const proxyStorage = new AsyncLocalStorage<string | null>();
208
208
 
209
209
  export function normalizeProxyUrl(value: unknown, source: string): string | null {
210
210
  if (value === undefined || value === null) return null;
211
- if (typeof value !== "string") throw new Error(`${source} must be an http(s) proxy URL string`);
211
+ if (typeof value !== "string") throw new Error(`${source} must be an http(s) or socks proxy URL string`);
212
212
  const trimmed = value.trim();
213
213
  if (!trimmed) return null;
214
214
  let parsed: URL;
@@ -217,8 +217,10 @@ export function normalizeProxyUrl(value: unknown, source: string): string | null
217
217
  } catch {
218
218
  throw new Error(`${source} must be a valid proxy URL: ${JSON.stringify(trimmed)}`);
219
219
  }
220
- if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
221
- throw new Error(`${source} must use the http:// or https:// scheme: ${trimmed}`);
220
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:" &&
221
+ parsed.protocol !== "socks4:" && parsed.protocol !== "socks4a:" &&
222
+ parsed.protocol !== "socks5:" && parsed.protocol !== "socks5h:") {
223
+ throw new Error(`${source} must use the http://, https://, or socks scheme: ${trimmed}`);
222
224
  }
223
225
  if (!parsed.hostname) throw new Error(`${source} must include a proxy host: ${trimmed}`);
224
226
  parsed.hash = "";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@herbertgao/pi-extensions",
3
- "version": "2026.9.2",
3
+ "version": "2026.9.3",
4
4
  "description": "Aggregate installer for HerbertGao-maintained Pi extensions.",
5
5
  "keywords": [
6
6
  "extensions",
@@ -47,6 +47,7 @@
47
47
  "@herbertgao/pi-cc-extensions": "0.9.0",
48
48
  "@herbertgao/pi-subagents": "0.17.1",
49
49
  "@herbertgao/resume-from": "0.2.0",
50
+ "@herbertgao/sol-pi": "0.2.0",
50
51
  "@juicesharp/rpiv-ask-user-question": "2.9.0",
51
52
  "@juicesharp/rpiv-config": "^2.9.0",
52
53
  "@luxusai/pi-hindsight": "0.12.0",
@@ -56,7 +57,7 @@
56
57
  "@modelcontextprotocol/sdk": "^1.29.0",
57
58
  "@mozilla/readability": "^0.6.0",
58
59
  "@napi-rs/keyring": "^1.3.0",
59
- "@narumitw/pi-btw": "0.58.0",
60
+ "@narumitw/pi-btw": "0.58.1",
60
61
  "@narumitw/pi-caffeinate": "0.49.7",
61
62
  "@narumitw/pi-tui-kit": "^0.59.0",
62
63
  "@noble/ed25519": "^3.1.0",
@@ -90,9 +91,9 @@
90
91
  "open": "^10.2.0",
91
92
  "p-limit": "^6.1.0",
92
93
  "pi-footer": "0.5.1",
93
- "pi-lens": "4.1.5",
94
+ "pi-lens": "4.1.6",
94
95
  "pi-mcp-adapter": "2.32.1",
95
- "pi-web-access": "0.28.0",
96
+ "pi-web-access": "0.29.0",
96
97
  "pidusage": "^4.0.1",
97
98
  "promise.try": "^2.0.1",
98
99
  "qrcode-terminal": "^0.12.0",
@@ -119,6 +120,7 @@
119
120
  "@herbertgao/pi-cc-extensions",
120
121
  "@herbertgao/pi-subagents",
121
122
  "@herbertgao/resume-from",
123
+ "@herbertgao/sol-pi",
122
124
  "@juicesharp/rpiv-ask-user-question",
123
125
  "@luxusai/pi-hindsight",
124
126
  "@narumitw/pi-btw",
@@ -144,6 +146,7 @@
144
146
  "extensions": [
145
147
  "./node_modules/@dietrichgebert/ponytail/pi-extension/index.js",
146
148
  "./node_modules/@herbertgao/pi-cc-extensions/extensions/index.ts",
149
+ "./node_modules/@herbertgao/sol-pi/src/sol-pi/index.ts",
147
150
  "./node_modules/@tifan/pi-copy-response/src/index.ts",
148
151
  "./node_modules/@herbertgao/resume-from/shims/pi/extensions/resume-from.js",
149
152
  "./node_modules/@tifan/pi-handoff/src/index.ts",
@@ -1,103 +0,0 @@
1
- import { Type } from "../clients/deps/typebox.js";
2
- import { compactRenderResult } from "./render-compact.js";
3
- import { LANGUAGES } from "./shared.js";
4
- function createAstDumpToolWithName(astGrepClient, name) {
5
- return {
6
- name,
7
- label: "AST-Grep Dump",
8
- description: "Dump the tree-sitter AST for a source snippet using ast-grep CLI. Use when ast_grep_search returns zero matches and you need exact node kinds, field names, or nesting. Named nodes only by default; includeAnonymous=true shows punctuation/CST nodes too.",
9
- promptSnippet: "Inspect AST node kinds before writing ast-grep patterns",
10
- renderResult: compactRenderResult(({ details, args, isError, lineCount, text }) => {
11
- const lang = details?.lang ?? (typeof args.lang === "string" ? args.lang : "");
12
- if (isError) {
13
- return `${name} ${lang} — ${text.split("\n")[0] ?? "error"}`.trim();
14
- }
15
- return `${name} ${lang} — ${lineCount} AST nodes`.replace(/\s+/g, " ");
16
- }),
17
- parameters: Type.Object({
18
- source: Type.String({
19
- description: "Source code snippet to parse and dump",
20
- }),
21
- lang: Type.String({
22
- enum: [...LANGUAGES],
23
- description: "Target language",
24
- }),
25
- includeAnonymous: Type.Optional(Type.Boolean({
26
- description: "Show anonymous punctuation/CST nodes too (default false)",
27
- })),
28
- }),
29
- async execute(_toolCallId, params, _signal, _onUpdate) {
30
- const source = typeof params.source === "string" ? params.source : "";
31
- const lang = typeof params.lang === "string"
32
- ? params.lang.replace(/^"|"$/g, "")
33
- : "";
34
- const includeAnonymous = params.includeAnonymous === true;
35
- try {
36
- if (!source.trim()) {
37
- return {
38
- content: [{ type: "text", text: "source is required" }],
39
- isError: true,
40
- details: { lang, includeAnonymous },
41
- };
42
- }
43
- if (_signal.aborted) {
44
- return {
45
- content: [
46
- { type: "text", text: "Error: operation aborted" },
47
- ],
48
- isError: true,
49
- details: { lang, includeAnonymous },
50
- };
51
- }
52
- if (!(await astGrepClient.ensureAvailable())) {
53
- return {
54
- content: [
55
- {
56
- type: "text",
57
- text: "ast-grep CLI not found. Install: npm i -D @ast-grep/cli",
58
- },
59
- ],
60
- isError: true,
61
- details: { lang, includeAnonymous },
62
- };
63
- }
64
- if (_signal.aborted) {
65
- return {
66
- content: [
67
- { type: "text", text: "Error: operation aborted" },
68
- ],
69
- isError: true,
70
- details: { lang, includeAnonymous },
71
- };
72
- }
73
- const result = await astGrepClient.dumpAst(source, lang, {
74
- includeAnonymous,
75
- });
76
- if (result.error) {
77
- return {
78
- content: [
79
- { type: "text", text: `Error: ${result.error}` },
80
- ],
81
- isError: true,
82
- details: { lang, includeAnonymous },
83
- };
84
- }
85
- return {
86
- content: [{ type: "text", text: result.output ?? "" }],
87
- details: { lang, includeAnonymous },
88
- };
89
- }
90
- catch (err) {
91
- const message = err instanceof Error ? err.message : String(err);
92
- return {
93
- content: [{ type: "text", text: `Error: ${message}` }],
94
- isError: true,
95
- details: { lang, includeAnonymous },
96
- };
97
- }
98
- },
99
- };
100
- }
101
- export function createAstGrepDumpTool(astGrepClient) {
102
- return createAstDumpToolWithName(astGrepClient, "ast_grep_dump");
103
- }