@herbertgao/pi-extensions 2026.9.2 → 2026.9.4

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 (255) hide show
  1. package/README.md +4 -2
  2. package/THIRD_PARTY_NOTICES.md +49 -0
  3. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +3 -2
  4. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +16 -11
  5. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-renderer.ts +20 -6
  6. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +12 -7
  7. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/result.ts +98 -0
  8. package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
  9. package/node_modules/@herbertgao/sol-pi/LICENSE +19 -0
  10. package/node_modules/@herbertgao/sol-pi/README.md +159 -0
  11. package/node_modules/@herbertgao/sol-pi/SECURITY.md +26 -0
  12. package/node_modules/@herbertgao/sol-pi/THIRD_PARTY_NOTICES.md +19 -0
  13. package/node_modules/@herbertgao/sol-pi/agents-install.md +150 -0
  14. package/node_modules/@herbertgao/sol-pi/assets/sol-pi-hero.png +0 -0
  15. package/node_modules/@herbertgao/sol-pi/docs/compatibility.md +69 -0
  16. package/node_modules/@herbertgao/sol-pi/docs/configuration.md +75 -0
  17. package/node_modules/@herbertgao/sol-pi/package.json +76 -0
  18. package/node_modules/@herbertgao/sol-pi/scripts/check-pi-compat.mjs +32 -0
  19. package/node_modules/@herbertgao/sol-pi/scripts/check-sol-pi-config.mjs +120 -0
  20. package/node_modules/@herbertgao/sol-pi/sol-pi.example.json +10 -0
  21. package/node_modules/@herbertgao/sol-pi/src/sol-pi/config.ts +135 -0
  22. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/file-queue.ts +74 -0
  23. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/index.ts +185 -0
  24. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/then-run.ts +128 -0
  25. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/archive.ts +53 -0
  26. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/candidate.ts +101 -0
  27. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/config.ts +71 -0
  28. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/index.ts +220 -0
  29. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/journal.ts +25 -0
  30. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/provider.ts +164 -0
  31. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/evidence-preserving-reducer/receipt.ts +177 -0
  32. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/observation-pack/index.ts +227 -0
  33. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/observation-pack/ledger.ts +20 -0
  34. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/observation-pack/observation.ts +252 -0
  35. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/economics.ts +237 -0
  36. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/extension.ts +455 -0
  37. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/index.ts +49 -0
  38. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/plan.ts +79 -0
  39. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/state.ts +208 -0
  40. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/tools.ts +100 -0
  41. package/node_modules/@herbertgao/sol-pi/src/sol-pi/index.ts +42 -0
  42. package/node_modules/@herbertgao/sol-pi/src/sol-pi/runtime-paths.ts +17 -0
  43. package/node_modules/@herbertgao/sol-pi/src/sol-pi/tui.ts +71 -0
  44. package/node_modules/@narumitw/pi-btw/dist/index.ts +12 -2
  45. package/node_modules/@narumitw/pi-btw/dist/index.ts.map +2 -2
  46. package/node_modules/@narumitw/pi-btw/package.json +1 -1
  47. package/node_modules/@narumitw/pi-btw/src/btw.ts +13 -2
  48. package/node_modules/pi-antigravity/LICENSE +21 -0
  49. package/node_modules/pi-antigravity/README.md +194 -0
  50. package/node_modules/pi-antigravity/package.json +67 -0
  51. package/node_modules/pi-antigravity/src/auth/index.ts +14 -0
  52. package/node_modules/pi-antigravity/src/auth/oauth.ts +442 -0
  53. package/node_modules/pi-antigravity/src/client/client.ts +561 -0
  54. package/node_modules/pi-antigravity/src/client/index.ts +1 -0
  55. package/node_modules/pi-antigravity/src/diagnostics/diagnostics.ts +96 -0
  56. package/node_modules/pi-antigravity/src/diagnostics/index.ts +1 -0
  57. package/node_modules/pi-antigravity/src/image/image.ts +336 -0
  58. package/node_modules/pi-antigravity/src/image/index.ts +1 -0
  59. package/node_modules/pi-antigravity/src/index.ts +280 -0
  60. package/node_modules/pi-antigravity/src/models/discovery.ts +154 -0
  61. package/node_modules/pi-antigravity/src/models/grouping.ts +424 -0
  62. package/node_modules/pi-antigravity/src/models/index.ts +3 -0
  63. package/node_modules/pi-antigravity/src/models/models.ts +500 -0
  64. package/node_modules/pi-antigravity/src/stream/index.ts +1 -0
  65. package/node_modules/pi-antigravity/src/stream/stream.ts +1460 -0
  66. package/node_modules/pi-antigravity/src/types/enums.ts +42 -0
  67. package/node_modules/pi-antigravity/src/types/index.ts +2 -0
  68. package/node_modules/pi-antigravity/src/types/types.ts +292 -0
  69. package/node_modules/pi-antigravity/src/usage/index.ts +1 -0
  70. package/node_modules/pi-antigravity/src/usage/usage.ts +371 -0
  71. package/node_modules/pi-antigravity/src/utils/http.ts +91 -0
  72. package/node_modules/pi-antigravity/src/utils/index.ts +3 -0
  73. package/node_modules/pi-antigravity/src/utils/security.ts +73 -0
  74. package/node_modules/pi-antigravity/src/utils/util.ts +132 -0
  75. package/node_modules/pi-antigravity/tsconfig.json +21 -0
  76. package/node_modules/pi-lens/CHANGELOG.md +176 -0
  77. package/node_modules/pi-lens/README.md +13 -8
  78. package/node_modules/pi-lens/config/dependency-cruiser-eager-allowlist.json +3 -1
  79. package/node_modules/pi-lens/dist/clients/analysed-root.js +1 -0
  80. package/node_modules/pi-lens/dist/clients/ast-grep-tool-logger.js +1 -1
  81. package/node_modules/pi-lens/dist/clients/biome-client.js +13 -2
  82. package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +2 -0
  83. package/node_modules/pi-lens/dist/clients/cache-observability.js +122 -1
  84. package/node_modules/pi-lens/dist/clients/complexity-client.js +5 -0
  85. package/node_modules/pi-lens/dist/clients/config-diagnostic-codes.js +2 -0
  86. package/node_modules/pi-lens/dist/clients/config-resolve.js +6 -3
  87. package/node_modules/pi-lens/dist/clients/config-schema.js +17 -0
  88. package/node_modules/pi-lens/dist/clients/config-warn.js +2 -2
  89. package/node_modules/pi-lens/dist/clients/dead-code-client.js +8 -1
  90. package/node_modules/pi-lens/dist/clients/dependency-checker.js +5 -1
  91. package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +38 -15
  92. package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +1 -1
  93. package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +5 -1
  94. package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +2 -1
  95. package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +2 -3
  96. package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +4 -3
  97. package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +2 -1
  98. package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +2 -1
  99. package/node_modules/pi-lens/dist/clients/dispatch/runners/dart-analyze.js +2 -1
  100. package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +2 -1
  101. package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +2 -1
  102. package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +2 -1
  103. package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +2 -1
  104. package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +2 -1
  105. package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +2 -1
  106. package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +2 -1
  107. package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +2 -1
  108. package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +2 -1
  109. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +3 -1
  110. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +2 -1
  111. package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +2 -1
  112. package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +2 -1
  113. package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +2 -1
  114. package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +19 -1
  115. package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +3 -2
  116. package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +2 -1
  117. package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +2 -1
  118. package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +2 -1
  119. package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +2 -1
  120. package/node_modules/pi-lens/dist/clients/dispatch/runners/prisma-validate.js +2 -1
  121. package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +12 -12
  122. package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +2 -1
  123. package/node_modules/pi-lens/dist/clients/dispatch/runners/rubocop.js +2 -1
  124. package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +2 -2
  125. package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +12 -11
  126. package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +2 -1
  127. package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +2 -1
  128. package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +2 -2
  129. package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.js +2 -1
  130. package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +3 -2
  131. package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +3 -2
  132. package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +2 -1
  133. package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +2 -1
  134. package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +2 -1
  135. package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +2 -1
  136. package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +2 -1
  137. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +5 -0
  138. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +2 -2
  139. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +8 -2
  140. package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +2 -1
  141. package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +4 -3
  142. package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +2 -1
  143. package/node_modules/pi-lens/dist/clients/effective-config.js +12 -2
  144. package/node_modules/pi-lens/dist/clients/extension-log.js +2 -0
  145. package/node_modules/pi-lens/dist/clients/file-role.js +18 -1
  146. package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +4 -0
  147. package/node_modules/pi-lens/dist/clients/formatters.js +54 -188
  148. package/node_modules/pi-lens/dist/clients/generation-guard.js +4 -0
  149. package/node_modules/pi-lens/dist/clients/gitleaks-client.js +42 -6
  150. package/node_modules/pi-lens/dist/clients/govulncheck-client.js +48 -7
  151. package/node_modules/pi-lens/dist/clients/installer/index.js +196 -52
  152. package/node_modules/pi-lens/dist/clients/jscpd-client.js +9 -1
  153. package/node_modules/pi-lens/dist/clients/knip-client.js +9 -2
  154. package/node_modules/pi-lens/dist/clients/language-profile.js +12 -2
  155. package/node_modules/pi-lens/dist/clients/latency-logger.js +2 -0
  156. package/node_modules/pi-lens/dist/clients/lens-config.js +4 -0
  157. package/node_modules/pi-lens/dist/clients/lsp/config.js +36 -7
  158. package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +24 -1
  159. package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +78 -0
  160. package/node_modules/pi-lens/dist/clients/lsp/index.js +281 -45
  161. package/node_modules/pi-lens/dist/clients/lsp/server.js +62 -15
  162. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +37 -4
  163. package/node_modules/pi-lens/dist/clients/mcp/analyze.js +3 -0
  164. package/node_modules/pi-lens/dist/clients/mcp/session.js +2 -0
  165. package/node_modules/pi-lens/dist/clients/opengrep-client.js +2 -0
  166. package/node_modules/pi-lens/dist/clients/package-manager.js +2 -1
  167. package/node_modules/pi-lens/dist/clients/php-cs-fixer-config.js +8 -3
  168. package/node_modules/pi-lens/dist/clients/pipeline.js +3 -2
  169. package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +38 -10
  170. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +10 -9
  171. package/node_modules/pi-lens/dist/clients/project-lens-config.js +3 -0
  172. package/node_modules/pi-lens/dist/clients/read-guard-logger.js +2 -0
  173. package/node_modules/pi-lens/dist/clients/review-graph-logger.js +2 -0
  174. package/node_modules/pi-lens/dist/clients/ruff-client.js +18 -9
  175. package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +9 -0
  176. package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +5 -0
  177. package/node_modules/pi-lens/dist/clients/runtime-session.js +13 -4
  178. package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +4 -1
  179. package/node_modules/pi-lens/dist/clients/runtime-turn.js +48 -1
  180. package/node_modules/pi-lens/dist/clients/security-scan-client.js +2 -2
  181. package/node_modules/pi-lens/dist/clients/session-event-guard.js +69 -1
  182. package/node_modules/pi-lens/dist/clients/sg-runner.js +2 -1
  183. package/node_modules/pi-lens/dist/clients/situational-tool-telemetry.js +108 -0
  184. package/node_modules/pi-lens/dist/clients/test-runner-client.js +291 -76
  185. package/node_modules/pi-lens/dist/clients/tool-config.js +199 -0
  186. package/node_modules/pi-lens/dist/clients/tool-cwd.js +299 -0
  187. package/node_modules/pi-lens/dist/clients/tool-probe.js +53 -0
  188. package/node_modules/pi-lens/dist/clients/tool-set-policy.js +42 -0
  189. package/node_modules/pi-lens/dist/clients/trivy-client.js +9 -1
  190. package/node_modules/pi-lens/dist/clients/turn-context.js +52 -0
  191. package/node_modules/pi-lens/dist/clients/widget-state.js +4 -3
  192. package/node_modules/pi-lens/dist/index.js +21969 -20005
  193. package/node_modules/pi-lens/dist/mcp/analyze-cli.js +3 -2
  194. package/node_modules/pi-lens/dist/mcp/server.js +135 -159
  195. package/node_modules/pi-lens/dist/tools/activate-tools.js +10 -7
  196. package/node_modules/pi-lens/dist/tools/ast-grep-outline.js +2 -13
  197. package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +8 -13
  198. package/node_modules/pi-lens/dist/tools/ast-grep-search.js +83 -39
  199. package/node_modules/pi-lens/dist/tools/effective-config.js +4 -3
  200. package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +1 -10
  201. package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +353 -85
  202. package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +21 -110
  203. package/node_modules/pi-lens/dist/tools/lsp-navigation.js +20 -44
  204. package/node_modules/pi-lens/dist/tools/module-report.js +5 -9
  205. package/node_modules/pi-lens/dist/tools/project-report.js +9 -17
  206. package/node_modules/pi-lens/dist/tools/render-compact.js +280 -1
  207. package/node_modules/pi-lens/dist/tools/symbol-search.js +2 -2
  208. package/node_modules/pi-lens/docs/agent-guide.md +3 -4
  209. package/node_modules/pi-lens/docs/agent-tools.md +46 -22
  210. package/node_modules/pi-lens/docs/configuration.md +9 -0
  211. package/node_modules/pi-lens/docs/environment-variables.md +0 -5
  212. package/node_modules/pi-lens/docs/features.md +5 -5
  213. package/node_modules/pi-lens/docs/globalconfig.md +11 -1
  214. package/node_modules/pi-lens/docs/mcp.md +13 -1
  215. package/node_modules/pi-lens/docs/pi-lens-fixer.md +71 -0
  216. package/node_modules/pi-lens/docs/pi-lens-investigator.md +15 -0
  217. package/node_modules/pi-lens/docs/pi-lens-monitor.md +88 -0
  218. package/node_modules/pi-lens/docs/pi-lens-reviewer.md +35 -0
  219. package/node_modules/pi-lens/docs/pi-lens-subagent.md +12 -4
  220. package/node_modules/pi-lens/docs/public-api-stability.md +1 -0
  221. package/node_modules/pi-lens/docs/real-harness.md +46 -0
  222. package/node_modules/pi-lens/docs/release-qa-baseline.md +5 -1
  223. package/node_modules/pi-lens/docs/servercapabilities.md +1 -6
  224. package/node_modules/pi-lens/docs/settings.md +37 -2
  225. package/node_modules/pi-lens/docs/tools_improvement2.md +4 -4
  226. package/node_modules/pi-lens/docs/tree-sitter_rules_catalog.md +1 -1
  227. package/node_modules/pi-lens/docs/usage.md +13 -3
  228. package/node_modules/pi-lens/package.json +10 -1
  229. package/node_modules/pi-lens/rules/tree-sitter-queries/typescript/sql-injection.yml +7 -3
  230. package/node_modules/pi-lens/skills/pi-lens-ast-grep/SKILL.md +8 -6
  231. package/node_modules/pi-lens/skills/pi-lens-lsp-navigation/SKILL.md +19 -9
  232. package/node_modules/pi-web-access/CHANGELOG.md +29 -0
  233. package/node_modules/pi-web-access/README.md +33 -22
  234. package/node_modules/pi-web-access/abortable.ts +17 -0
  235. package/node_modules/pi-web-access/crawl4ai.ts +204 -0
  236. package/node_modules/pi-web-access/credential-source.ts +1 -0
  237. package/node_modules/pi-web-access/curator-page.ts +20 -2
  238. package/node_modules/pi-web-access/curator-run.ts +44 -0
  239. package/node_modules/pi-web-access/curator-server.ts +3 -1
  240. package/node_modules/pi-web-access/duckduckgo.ts +1 -1
  241. package/node_modules/pi-web-access/extract.ts +57 -12
  242. package/node_modules/pi-web-access/fetch-params.ts +1 -1
  243. package/node_modules/pi-web-access/gemini-search.ts +9 -5
  244. package/node_modules/pi-web-access/index.ts +25 -18
  245. package/node_modules/pi-web-access/openai-search.ts +35 -13
  246. package/node_modules/pi-web-access/package.json +2 -2
  247. package/node_modules/pi-web-access/page-query.ts +5 -2
  248. package/node_modules/pi-web-access/query-rewrite.ts +5 -2
  249. package/node_modules/pi-web-access/serpapi.ts +220 -0
  250. package/node_modules/pi-web-access/ssrf-protection.ts +5 -1
  251. package/node_modules/pi-web-access/storage.ts +10 -0
  252. package/node_modules/pi-web-access/summary-review.ts +34 -21
  253. package/node_modules/pi-web-access/utils.ts +6 -4
  254. package/package.json +11 -5
  255. package/node_modules/pi-lens/dist/tools/ast-dump.js +0 -103
@@ -0,0 +1,19 @@
1
+ # Third-Party Notices
2
+
3
+ SoL-Pi does not vendor third-party source code. Its npm tarball contains only SoL-Pi source, documentation, tests-excluded assets, and project metadata.
4
+
5
+ ## Runtime peer dependencies
6
+
7
+ The following packages are supplied by the user's Pi installation and retain their own licenses:
8
+
9
+ | Package | Development-tested version | License | Source |
10
+ | --- | ---: | --- | --- |
11
+ | `@earendil-works/pi-agent-core` | 0.84.2 | MIT | <https://github.com/earendil-works/pi> |
12
+ | `@earendil-works/pi-ai` | 0.84.2 | MIT | <https://github.com/earendil-works/pi> |
13
+ | `@earendil-works/pi-coding-agent` | 0.84.2 | MIT | <https://github.com/earendil-works/pi> |
14
+ | `@earendil-works/pi-tui` | 0.84.2 | MIT | <https://github.com/earendil-works/pi> |
15
+ | `typebox` | 1.3.7 | MIT | <https://github.com/sinclairzx81/typebox> |
16
+
17
+ ## Development-only dependencies
18
+
19
+ `@types/node` (MIT), TypeScript (Apache-2.0), and Vitest (MIT) are used to type-check and test the repository. They are not included in the SoL-Pi npm tarball. Exact versions and transitive dependency metadata are recorded in `package-lock.json`.
@@ -0,0 +1,150 @@
1
+ # SoL-Pi Agent Installation and Configuration Protocol
2
+
3
+ This is the canonical procedure for Codex, Claude Code, and other coding agents that install, configure, or validate SoL-Pi from a full source checkout. Follow the phases in order. Explicit user instructions take precedence. An extracted npm package is not a substitute for the checkout because it does not contain the test suite.
4
+
5
+ Installation and configuration are complete only when Pi remains unmodified, the repository checks pass, Pi lists the package, all four mechanisms are enabled in one effective `sol-pi.json`, and Pi starts without an extension error.
6
+
7
+ ## Rules
8
+
9
+ - Do not modify, patch, fork, or vendor upstream Pi. SoL-Pi must load as a standalone extension through Pi's public package interface.
10
+ - Use Node.js 22.19 or newer and the tested Pi release `@earendil-works/pi-coding-agent@0.84.2`. Treat a different Pi version as a compatibility change and rerun the full suite before using it.
11
+ - Do not clean, reset, switch, or overwrite unrelated repository changes.
12
+ - Do not print, log, commit, upload, or include any secret in a command line. Check only whether a credential is present.
13
+ - Keep SoL-Pi settings in `sol-pi.json`. The Evidence-Preserving Reducer provider/model route is a SoL-Pi setting; provider URLs, credentials, the main agent model, and shell behavior remain Pi settings.
14
+ - Keep persistent artifacts under Pi's session-derived `sol-pi/<session-id>/` root; do not configure a separate storage path.
15
+
16
+ ## Inputs
17
+
18
+ Resolve these values before making changes:
19
+
20
+ - `sol_pi_root`: absolute path to the intended SoL-Pi checkout;
21
+ - `target_project`: project in which Pi will run;
22
+ - install scope: project-local or user-wide;
23
+ - exact SoL-Pi branch and commit.
24
+
25
+ Do not guess an ambiguous path or install scope.
26
+
27
+ ## Phase 1: validate the checkout
28
+
29
+ From `sol_pi_root`, record the repository state without changing it:
30
+
31
+ ```bash
32
+ git status --short --branch
33
+ git rev-parse HEAD
34
+ node --version
35
+ npm --version
36
+ ```
37
+
38
+ Require Node.js 22.19 or newer. Install from the lockfile and run the source checks:
39
+
40
+ ```bash
41
+ npm ci --ignore-scripts
42
+ npm run check
43
+ npm audit --audit-level=high
44
+ node scripts/check-pi-compat.mjs
45
+ npx vitest run tests/all-mechanisms.test.ts
46
+ ```
47
+
48
+ `npm run check` covers type checking, the complete test suite, and package inspection. `tests/all-mechanisms.test.ts` confirms that one all-enabled configuration registers all four mechanisms against Pi's public extension API. The tests run without a model provider.
49
+
50
+ Stop if any command fails. Do not hide a failure with `|| true` or replace `npm ci` with an unlocked install.
51
+
52
+ ## Phase 2: install Pi and SoL-Pi
53
+
54
+ Install the tested Pi release without changing its source:
55
+
56
+ ```bash
57
+ npm install --global --ignore-scripts @earendil-works/pi-coding-agent@0.84.2
58
+ pi --version
59
+ ```
60
+
61
+ Require `pi --version` to report `0.84.2`.
62
+
63
+ For a project-local registration, run this from `target_project` and substitute the resolved absolute `sol_pi_root`:
64
+
65
+ ```bash
66
+ pi install "/absolute/path/to/SoL-Pi" --local --approve
67
+ pi list --approve
68
+ ```
69
+
70
+ For a user-wide registration, omit `--local`:
71
+
72
+ ```bash
73
+ pi install "/absolute/path/to/SoL-Pi" --approve
74
+ pi list --approve
75
+ ```
76
+
77
+ The `pi list` output must show the exact SoL-Pi source in the selected scope. Do not install the same checkout in both scopes. A project-local registration must run only in a trusted project; use `--approve` for automated invocations unless trust has already been explicitly persisted.
78
+
79
+ ## Phase 3: configure all four mechanisms
80
+
81
+ SoL-Pi defaults every mechanism to disabled. For this managed installation, create exactly one effective configuration with every mechanism enabled:
82
+
83
+ ```json
84
+ {
85
+ "version": 1,
86
+ "actionFusion": true,
87
+ "observationPack": true,
88
+ "evidencePreservingReducer": true,
89
+ "evidencePreservingReducerProvider": "provider-id",
90
+ "evidencePreservingReducerModel": "model-id",
91
+ "onlineContextCompact": true,
92
+ "cacheWriteReadRatio": 12.5
93
+ }
94
+ ```
95
+
96
+ `evidencePreservingReducerProvider` and `evidencePreservingReducerModel` select the nested reducer route that Evidence-Preserving Reducer resolves through Pi's model registry. They default to the built-in reducer route and must be non-empty strings when supplied. Change them only when a different reducer model is intended.
97
+
98
+ `cacheWriteReadRatio` is the only pricing-related input SoL-Pi reads. It defaults to `12.5`, accepts any finite non-negative number, and treats `0` as an explicit statement that a cache write adds no cost relative to a cache read. SoL-Pi does not inspect Pi model prices. The value controls one compaction decision and is not a bill estimate. The default follows the GPT-5.6 Sol OpenAI Standard cache-write/read ratio checked on 2026-08-21; see [OpenAI API pricing](https://developers.openai.com/api/docs/pricing). Change it when a different policy is required.
99
+
100
+ Use one location matching the selected scope. Resolve the directory through Pi; the official Pi defaults are shown in parentheses:
101
+
102
+ - project-local: `<target_project>/<Pi config directory>/sol-pi.json` (`<target_project>/.pi/sol-pi.json`);
103
+ - user-wide: `<Pi agent directory>/sol-pi.json` (`~/.pi/agent/sol-pi.json`).
104
+
105
+ SoL-Pi uses Pi's public `CONFIG_DIR_NAME` and `getAgentDir()` APIs. Do not assume the defaults when Pi reports different directories.
106
+
107
+ The project file replaces the user-wide file; the two are not merged. If both exist, inspect them and obtain direction before changing either one. Unknown keys, unsupported versions, malformed JSON, non-boolean feature values, invalid reducer model fields, and invalid ratios must remain fatal.
108
+
109
+ Do not put provider URL, credentials, shell path, command prefix, storage path, or run ID in `sol-pi.json`. SoL-Pi either reads those values from Pi or derives them from the Pi session.
110
+
111
+ SoL-Pi reads no dedicated environment variables. Evidence-Preserving Reducer uses the configured reducer provider/model route and Pi-managed authentication. Configure credentials in Pi and do not copy them into `sol-pi.json`.
112
+
113
+ From `sol_pi_root`, validate the exact effective file:
114
+
115
+ ```bash
116
+ node scripts/check-sol-pi-config.mjs \
117
+ --config /absolute/path/to/effective/sol-pi.json \
118
+ --require-all-enabled
119
+ ```
120
+
121
+ Require exit status 0 and retain its JSON output. The check applies SoL-Pi's default values, rejects unknown keys and wrong types, and confirms all four mechanisms are enabled. A partially enabled file can be valid SoL-Pi configuration, but it does not satisfy this all-enabled profile.
122
+
123
+ ## Phase 4: verify the installation
124
+
125
+ 1. Run `pi list --approve` from `target_project` and confirm the expected SoL-Pi source and scope.
126
+ 2. Run `check-sol-pi-config.mjs --require-all-enabled` against the effective `sol-pi.json`.
127
+ 3. Re-run `npx vitest run tests/all-mechanisms.test.ts` from `sol_pi_root`.
128
+ 4. Start Pi with `--offline --approve`, send no prompt, confirm there is no extension load error, and exit.
129
+ 5. Confirm that upstream Pi was not patched and that the SoL-Pi checkout contains no vendored Pi monorepo source.
130
+
131
+ ## Completion report
132
+
133
+ Report:
134
+
135
+ - SoL-Pi absolute path, branch, and commit;
136
+ - repository state before and after installation;
137
+ - Node, npm, and Pi versions;
138
+ - install scope and the exact entry shown by `pi list`;
139
+ - effective config path, four enabled flags, EPR reducer provider/model, and `cacheWriteReadRatio`, without secrets;
140
+ - every validation command and result;
141
+ - any blocker or deviation.
142
+
143
+ Do not describe the installation as successful if a required check is missing.
144
+
145
+ ## Agent entry files
146
+
147
+ `agents-install.md` is the single source of truth, but agents do not universally auto-discover arbitrary filenames. Root `AGENTS.md` tells Codex to read this file, while root `CLAUDE.md` imports it for Claude Code. Keep those entry files short and keep executable installation details here.
148
+
149
+ - [Codex `AGENTS.md` discovery](https://developers.openai.com/codex/guides/agents-md)
150
+ - [Claude Code project memory and imports](https://docs.anthropic.com/zh-CN/docs/claude-code/memory)
@@ -0,0 +1,69 @@
1
+ # Pi Compatibility
2
+
3
+ SoL-Pi is developed and tested against `@earendil-works/pi-coding-agent` 0.84.2. Its public API surface is also type-checked and exercised against Pi 0.81.1, the base used by the original Pi fork. The runtime range is deliberately expressed as a peer dependency because Pi owns installation and upgrade of its packages.
4
+
5
+ SoL-Pi imports only public package exports:
6
+
7
+ - `createEditToolDefinition`
8
+ - `createWriteToolDefinition`
9
+ - `createBashToolDefinition`
10
+ - extension types and `ExtensionAPI.registerTool`
11
+ - `context`, `before_provider_request`, `tool_result`, `turn_end`, `agent_settled`, and `session_before_tree` extension events
12
+ - native compaction events, `ExtensionContext.getContextUsage()`, and `ExtensionContext.compact()`
13
+ - `ExtensionContext.model` and `ExtensionContext.modelRegistry`
14
+ - the public session-manager methods exposed through `ExtensionContext`
15
+
16
+ ## Action Fusion
17
+
18
+ The built-in edit/write definitions capture their working directory, so SoL-Pi caches one definition per `ctx.cwd`. Its own per-file queue surrounds the built-in mutation and follow-up command. It does not nest Pi's built-in mutation queue.
19
+
20
+ Action Fusion decodes `file://` targets with Node's `fileURLToPath()` before resolving the queue and hash-check path. This keeps file URLs, including percent-encoded filenames and Pi's optional `@` prefix, aligned with the file handled by the built-in mutation tool.
21
+
22
+ The queue covers only fused operations registered by this SoL-Pi instance. External processes, direct built-in-tool calls outside the replacement, and unrelated extensions are not globally locked. SoL-Pi hashes the target immediately before launching `then_run` and skips the command if it observes an intervening content change.
23
+
24
+ When another extension already owns `write`, Action Fusion leaves that tool in place and only registers its `edit` replacement. When `pi-automode` exposes `automode_inspect`, Action Fusion registers neither mutation replacement: nested `then_run` cannot re-enter Pi's public `tool_call` permission pipeline, so disabling the fusion is the safe fallback.
25
+
26
+ ## ObservationPack
27
+
28
+ ObservationPack changes only the messages projected through the public `context` event. Stored session history remains intact. Original bytes and the JSONL ledger live under the session-derived SoL-Pi directory.
29
+
30
+ ## Evidence-Preserving Reducer
31
+
32
+ The reducer handles public `tool_result` events and resolves the configured reducer provider/model through Pi's model registry before calling `ExtensionContext.modelRegistry.complete()` when available. For the Pi 0.81.1 fork, which exposes no registry `complete()` method, it resolves authentication for that reducer model through `getApiKeyAndHeaders()` and calls the shared `@earendil-works/pi-ai/compat` completion API. The reducer preserves the original result whenever the configured reducer model is unavailable or eligibility, model-call, schema, source-hash, exact-quote, size, or likely-secret checks fail.
33
+
34
+ All persistent paths use `SessionManager.getSessionDir()` and `getSessionId()`, which are present in both the fork and Pi 0.84.2. SoL-Pi creates no configurable storage-path surface.
35
+
36
+ The unpublished shared artifact layout is not read or migrated. Each session starts from its own `<sessionDir>/sol-pi/<sessionId>/` directory.
37
+
38
+ ## Online Context Compact
39
+
40
+ Online Context Compact uses ordinary public `context` and `before_provider_request` handlers instead of fork-only post-transform observer methods. Public handlers run in extension load order, so the SoL-Pi entrypoint registers Online Context Compact after its other context transformers. A third-party transformer loaded later is outside the context-growth observation used by its estimate.
41
+
42
+ Before selecting or executing a boundary compaction, it also checks the optional `Symbol.for("pi-subagents:manager")` registry exposed by `pi-subagents`. A running top-level subagent, or an unreadable registry, suppresses that compaction rather than risking a context rewrite during delegated work. When the registry is absent, the check is a no-op.
43
+
44
+ Pi does not expose its active retained-tail compaction setting through the public extension context. The standalone extension therefore uses the documented Pi 0.84.2 default of 20,000 tokens for its economic estimate. Its programmatic factory accepts an explicit matching value for a non-default Pi setting.
45
+
46
+ Pi 0.84.2's `ExtensionContext.compact()` aborts the active agent before it summarizes, and `agent_settled` fires only once a whole run has drained every turn, retry, auto-compaction, and queued continuation. A plan boundary that selects compaction therefore saves its plan and progress state, calls `ExtensionContext.abort()` to stop the run, and runs compaction from the `agent_settled` that stop produces. The handler awaits the compaction's own `onComplete`/`onError` callbacks. On success, the extension sends a hidden reminder through public `ExtensionAPI.sendMessage()` with `triggerTurn: true`, so Pi starts a new turn against the compacted context and rebuilds the plan even when the native summary omits that instruction.
47
+
48
+ A settlement barrier keeps the original `agent_settled` dispatch open until the triggered continuation settles. Print- and JSON-mode processes therefore complete the compact-and-continue sequence within the same Pi invocation; an outer driver does not need to resume the session or send `Continue working`. This continuation is armed only by a successful boundary compaction. Cancelling or exiting does not schedule one. A Pi build that never emits `agent_settled` starts no boundary compaction.
49
+
50
+ Pi 0.84.2 does not return a promise from `ExtensionAPI.sendMessage()`. The barrier is therefore verified for standalone SoL-Pi and depends on Pi starting the requested turn synchronously. A later-loaded third-party extension that performs long asynchronous work in its own `agent_settled` handler is outside this guarantee and needs an integration test with that extension set.
51
+
52
+ Pi reports the session as idle while an extension-requested manual compaction is running. SoL-Pi cancels `session_before_tree` during that interval to prevent tree navigation from moving the active leaf underneath the compaction. Navigation works normally after the compaction callback settles.
53
+
54
+ Online Context Compact reads `ExtensionContext.getContextUsage()` for both the context window and the provider-counted context size. When Pi reports no size — as it does between a compaction and the next answered request — the boundary falls back to its own estimate.
55
+
56
+ The standalone entry passes `cacheWriteReadRatio` from `sol-pi.json` directly into Online Context Compact's economic check. It does not inspect model price metadata. Changing models during a session does not change the ratio; users who want a different decision policy update the configuration and start a new session.
57
+
58
+ ## Interactive TUI
59
+
60
+ The lightning savings treatment uses Pi 0.84.2's public `renderCall`,
61
+ `renderResult`, `ctx.ui.notify()`, and keyed `ctx.ui.setStatus()` APIs. It checks
62
+ `ctx.mode === "tui"` rather than `ctx.hasUI`, because RPC mode also reports UI
63
+ support. The renderer therefore changes only the interactive terminal display;
64
+ it does not change session messages, provider requests, tool results, JSON
65
+ events, print output, or RPC UI requests.
66
+
67
+ ## Test doubles
68
+
69
+ The test suite drives every extension through the same public `ExtensionAPI` and `ExtensionContext` surface Pi provides, over a real public `SessionManager`, with no provider registered. That keeps the suite zero-spend and independent of the deleted Pi monorepo test harness. Suites that need a genuine session tree — branch order, compaction entries, custom entries, resume — use `SessionManager.inMemory()` or `SessionManager.create()` rather than reimplementing them.
@@ -0,0 +1,75 @@
1
+ # Configuration
2
+
3
+ SoL-Pi reads one effective JSON configuration file at extension startup. It uses Pi's public `CONFIG_DIR_NAME` and `getAgentDir()` APIs rather than assuming fixed directories.
4
+
5
+ ## Search order
6
+
7
+ 1. `<working-directory>/<Pi config directory>/sol-pi.json`, only after Pi marks the project trusted
8
+ 2. `<Pi agent directory>/sol-pi.json`
9
+ 3. Built-in defaults when neither file exists
10
+
11
+ For the official Pi distribution, the first two locations normally resolve to `.pi/sol-pi.json` and `~/.pi/agent/sol-pi.json`.
12
+
13
+ The project file replaces the global file. SoL-Pi does not merge them.
14
+
15
+ ## Schema
16
+
17
+ ```json
18
+ {
19
+ "version": 1,
20
+ "actionFusion": false,
21
+ "observationPack": false,
22
+ "evidencePreservingReducer": false,
23
+ "evidencePreservingReducerProvider": "provider-id",
24
+ "evidencePreservingReducerModel": "model-id",
25
+ "onlineContextCompact": false,
26
+ "cacheWriteReadRatio": 12.5
27
+ }
28
+ ```
29
+
30
+ Feature keys may be omitted and then default to `false`. `cacheWriteReadRatio` may be omitted and then defaults to `12.5`; when present it must be a finite non-negative number, and `0` explicitly means that a cache write adds no cost relative to a cache read. `evidencePreservingReducerProvider` and `evidencePreservingReducerModel` may be omitted and then use the built-in reducer route; when present each must be a non-empty string. Unknown keys, unsupported versions, malformed JSON, non-boolean feature values, invalid ratios, and invalid reducer model fields stop extension loading with a direct error.
31
+
32
+ For the managed all-enabled installation described in the [agent installation and configuration protocol](../agents-install.md), validate the effective file before starting Pi:
33
+
34
+ ```bash
35
+ node scripts/check-sol-pi-config.mjs \
36
+ --config /absolute/path/to/effective/sol-pi.json \
37
+ --require-all-enabled
38
+ ```
39
+
40
+ This preflight does not make every valid SoL-Pi configuration all-enabled. Without `--require-all-enabled`, omitted feature keys retain their normal `false` defaults. The managed workflow uses the flag because its acceptance criterion is that all four mechanisms are active.
41
+
42
+ ## Feature behavior
43
+
44
+ - `actionFusion`: registers SoL-Pi replacements for Pi's `edit` and `write` tools.
45
+ - `observationPack`: registers `obs_recall` and a provider-context projection handler.
46
+ - `evidencePreservingReducer`: registers a `tool_result` handler and delegates long diagnostic-log reduction to the configured reducer provider/model.
47
+ - `evidencePreservingReducerProvider`: provider namespace used to resolve the reducer model through Pi's model registry.
48
+ - `evidencePreservingReducerModel`: model id used for Evidence-Preserving Reducer.
49
+ - `onlineContextCompact`: registers `update_plan` and boundary-driven native compaction after the other SoL-Pi context transformers.
50
+ - `cacheWriteReadRatio`: supplies the single economic decision ratio used by Online Context Compact.
51
+
52
+ ## Evidence-Preserving Reducer runtime inputs
53
+
54
+ The release entry supplies the run label and session-derived storage. It uses one configurable model route:
55
+
56
+ - **Reducer provider/model** — from `evidencePreservingReducerProvider` and `evidencePreservingReducerModel` in the effective `sol-pi.json`. If omitted, SoL-Pi uses its built-in reducer route. SoL-Pi resolves that model through Pi's model registry and still relies on Pi-managed authentication; do not put credentials in `sol-pi.json`.
57
+
58
+ ## Online Context Compact runtime inputs
59
+
60
+ The release entry uses two runtime inputs:
61
+
62
+ - **Context window** — from `ExtensionContext.getContextUsage()`, used for window-pressure protection.
63
+ - **Cache write/read ratio** — from `cacheWriteReadRatio` in the effective `sol-pi.json`. The value remains fixed for the session and is not recomputed when the model changes. It drives one runtime decision and is not a cost report.
64
+
65
+ The configured ratio stays fixed for the loaded extension. The mechanism stores its current plan, progress summaries, request horizon, context growth, and compaction debt as versioned custom entries in Pi's session log. After a successful compaction it sends one hidden, generic message with `triggerTurn: true`, which starts a new turn and instructs the assistant to rebuild its plan. A settlement barrier keeps print and JSON modes in the same Pi invocation until that continuation settles, so callers do not need to resume the session or inject `Continue working`. Cancelling or exiting does not schedule an automatic continuation. The mechanism creates no separate Online Context Compact files. The programmatic factory exposes only a matching retained-tail value for installations whose Pi compaction setting differs from the default.
66
+
67
+ ## Pi integration
68
+
69
+ SoL-Pi reads no dedicated environment variables. Evidence-Preserving Reducer resolves its configured reducer provider/model through `ExtensionContext.modelRegistry` and uses Pi-managed authentication. If the configured reducer model is unavailable or the nested model call fails, the original tool result continues unchanged.
70
+
71
+ SoL-Pi does not configure shell paths, command prefixes, storage paths, run IDs, provider URLs, reasoning levels, timeouts, or per-mechanism enable flags through environment variables. Apart from the EPR reducer provider/model route in `sol-pi.json`, model selection remains with Pi. Action Fusion uses Pi's default shell behavior. Persistent artifacts are derived from Pi's session directory and session ID.
72
+
73
+ ## Trust
74
+
75
+ A project-local config can enable file mutation, shell execution, local archival, and remote diagnostic-log reduction. SoL-Pi waits for Pi's `session_start` context and ignores the project file unless `ctx.isProjectTrusted()` is true. Prefer the global file when you want one personal configuration across trusted projects.
@@ -0,0 +1,76 @@
1
+ {
2
+ "name": "@herbertgao/sol-pi",
3
+ "version": "0.2.0",
4
+ "description": "Token-efficient context and tool extensions for Pi, maintained from NVlabs/SoL-Pi.",
5
+ "keywords": [
6
+ "pi-package",
7
+ "pi-extension",
8
+ "context-management",
9
+ "token-efficiency"
10
+ ],
11
+ "homepage": "https://github.com/HerbertGao/pi-extensions/tree/master/packages/sol-pi#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/HerbertGao/pi-extensions/issues"
14
+ },
15
+ "license": "MIT",
16
+ "author": "Herbert Gao",
17
+ "contributors": [
18
+ "NVIDIA Corporation"
19
+ ],
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/HerbertGao/pi-extensions.git",
23
+ "directory": "packages/sol-pi"
24
+ },
25
+ "files": [
26
+ "src/sol-pi",
27
+ "assets",
28
+ "docs/compatibility.md",
29
+ "docs/configuration.md",
30
+ "scripts/check-pi-compat.mjs",
31
+ "scripts/check-sol-pi-config.mjs",
32
+ "agents-install.md",
33
+ "README.md",
34
+ "LICENSE",
35
+ "SECURITY.md",
36
+ "THIRD_PARTY_NOTICES.md",
37
+ "sol-pi.example.json"
38
+ ],
39
+ "type": "module",
40
+ "publishConfig": {
41
+ "access": "public",
42
+ "provenance": true
43
+ },
44
+ "scripts": {
45
+ "test": "vitest run",
46
+ "typecheck": "tsc --noEmit",
47
+ "check": "npm run typecheck && npm test && npm pack --dry-run"
48
+ },
49
+ "peerDependencies": {
50
+ "@earendil-works/pi-agent-core": ">=0.84.2",
51
+ "@earendil-works/pi-ai": ">=0.84.2",
52
+ "@earendil-works/pi-coding-agent": ">=0.84.2",
53
+ "@earendil-works/pi-tui": ">=0.84.2",
54
+ "typebox": ">=1.3.7"
55
+ },
56
+ "devDependencies": {
57
+ "@types/node": "^24.0.0",
58
+ "typescript": "^7.0.2",
59
+ "vitest": "^4.0.18"
60
+ },
61
+ "engines": {
62
+ "node": ">=22.19.0"
63
+ },
64
+ "pi": {
65
+ "extensions": [
66
+ "./src/sol-pi/index.ts"
67
+ ]
68
+ },
69
+ "x-upstream": {
70
+ "package": "sol-pi",
71
+ "version": "0.1.0",
72
+ "reviewedVersion": "0.1.0",
73
+ "repository": "https://github.com/NVlabs/SoL-Pi",
74
+ "commit": "22277b7e0c3c46ba1259a6687f31fe39ade421a5"
75
+ }
76
+ }
@@ -0,0 +1,32 @@
1
+ /*
2
+ * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import {
7
+ CONFIG_DIR_NAME,
8
+ ModelRegistry,
9
+ SessionManager,
10
+ createBashToolDefinition,
11
+ createEditToolDefinition,
12
+ createWriteToolDefinition,
13
+ getAgentDir,
14
+ } from "@earendil-works/pi-coding-agent";
15
+ import { complete as completeCompat } from "@earendil-works/pi-ai/compat";
16
+
17
+ for (const [name, value] of Object.entries({
18
+ createBashToolDefinition,
19
+ createEditToolDefinition,
20
+ createWriteToolDefinition,
21
+ getApiKeyAndHeaders: ModelRegistry.prototype.getApiKeyAndHeaders,
22
+ getAgentDir,
23
+ piAiCompatComplete: completeCompat,
24
+ sessionManagerGetSessionDir: SessionManager.prototype.getSessionDir,
25
+ sessionManagerGetSessionId: SessionManager.prototype.getSessionId,
26
+ })) {
27
+ if (typeof value !== "function") throw new Error(`Missing public Pi API: ${name}`);
28
+ }
29
+
30
+ if (typeof CONFIG_DIR_NAME !== "string" || CONFIG_DIR_NAME.length === 0) {
31
+ throw new Error("Missing public Pi API: CONFIG_DIR_NAME");
32
+ }
@@ -0,0 +1,120 @@
1
+ /*
2
+ * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { readFileSync } from "node:fs";
7
+ import { resolve } from "node:path";
8
+
9
+ const FEATURE_KEYS = [
10
+ "actionFusion",
11
+ "observationPack",
12
+ "evidencePreservingReducer",
13
+ "onlineContextCompact",
14
+ ];
15
+ const DEFAULT_CACHE_WRITE_READ_RATIO = 12.5;
16
+ const DEFAULT_EPR_REDUCER_PROVIDER = ["openai", "codex"].join("-");
17
+ const DEFAULT_EPR_REDUCER_MODEL = ["gpt-5.6", "luna"].join("-");
18
+ const STRING_KEYS = ["evidencePreservingReducerModel", "evidencePreservingReducerProvider"];
19
+ const CONFIG_KEYS = new Set(["version", ...FEATURE_KEYS, ...STRING_KEYS, "cacheWriteReadRatio"]);
20
+
21
+ function fail(message) {
22
+ throw new Error(message);
23
+ }
24
+
25
+ function parseArguments(argv) {
26
+ const options = { config: undefined, requireAllEnabled: false };
27
+ const seen = new Set();
28
+ for (let index = 0; index < argv.length; index += 1) {
29
+ const argument = argv[index];
30
+ if (seen.has(argument)) fail(`duplicate option: ${argument}`);
31
+ if (argument === "--require-all-enabled") {
32
+ seen.add(argument);
33
+ options.requireAllEnabled = true;
34
+ continue;
35
+ }
36
+ if (argument !== "--config") fail(`unknown option: ${argument}`);
37
+ seen.add(argument);
38
+ const value = argv[index + 1];
39
+ if (!value || value.startsWith("--")) fail("missing value for --config");
40
+ options.config = value;
41
+ index += 1;
42
+ }
43
+ if (!options.config) fail("--config is required");
44
+ return options;
45
+ }
46
+
47
+ function readConfig(path) {
48
+ let text;
49
+ try {
50
+ text = readFileSync(path, "utf8");
51
+ } catch (error) {
52
+ fail(`unable to read config ${path}: ${error instanceof Error ? error.message : String(error)}`);
53
+ }
54
+ try {
55
+ return JSON.parse(text);
56
+ } catch (error) {
57
+ fail(`invalid JSON in config ${path}: ${error instanceof Error ? error.message : String(error)}`);
58
+ }
59
+ }
60
+
61
+ function validateConfig(value, requireAllEnabled) {
62
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
63
+ fail("config must be a JSON object");
64
+ }
65
+ for (const key of Object.keys(value)) {
66
+ if (!CONFIG_KEYS.has(key)) fail(`unknown key: ${key}`);
67
+ }
68
+ if (value.version !== 1) fail("version must be 1");
69
+
70
+ const effective = { version: 1 };
71
+ for (const key of FEATURE_KEYS) {
72
+ const configured = value[key];
73
+ if (configured !== undefined && typeof configured !== "boolean") fail(`${key} must be boolean`);
74
+ effective[key] = configured ?? false;
75
+ if (requireAllEnabled && effective[key] !== true) fail(`${key} must be true`);
76
+ }
77
+ const cacheWriteReadRatio = Object.hasOwn(value, "cacheWriteReadRatio")
78
+ ? value.cacheWriteReadRatio
79
+ : DEFAULT_CACHE_WRITE_READ_RATIO;
80
+ if (
81
+ typeof cacheWriteReadRatio !== "number" ||
82
+ !Number.isFinite(cacheWriteReadRatio) ||
83
+ cacheWriteReadRatio < 0
84
+ ) {
85
+ fail("cacheWriteReadRatio must be a finite non-negative number");
86
+ }
87
+ effective.cacheWriteReadRatio = cacheWriteReadRatio;
88
+ effective.evidencePreservingReducerModel = stringConfigValue(
89
+ value,
90
+ "evidencePreservingReducerModel",
91
+ DEFAULT_EPR_REDUCER_MODEL,
92
+ );
93
+ effective.evidencePreservingReducerProvider = stringConfigValue(
94
+ value,
95
+ "evidencePreservingReducerProvider",
96
+ DEFAULT_EPR_REDUCER_PROVIDER,
97
+ );
98
+
99
+ return {
100
+ ok: true,
101
+ all_enabled: FEATURE_KEYS.every((key) => effective[key] === true),
102
+ effective_config: effective,
103
+ };
104
+ }
105
+
106
+ function stringConfigValue(value, key, defaultValue) {
107
+ const configured = Object.hasOwn(value, key) ? value[key] : defaultValue;
108
+ if (typeof configured !== "string" || configured.trim().length === 0) fail(`${key} must be a non-empty string`);
109
+ return configured;
110
+ }
111
+
112
+ try {
113
+ const options = parseArguments(process.argv.slice(2));
114
+ const configPath = resolve(options.config);
115
+ const result = validateConfig(readConfig(configPath), options.requireAllEnabled);
116
+ console.log(JSON.stringify({ ...result, config: configPath }, null, 2));
117
+ } catch (error) {
118
+ console.error(`SoL-Pi configuration preflight failed: ${error instanceof Error ? error.message : String(error)}`);
119
+ process.exitCode = 1;
120
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 1,
3
+ "actionFusion": false,
4
+ "observationPack": false,
5
+ "evidencePreservingReducer": false,
6
+ "evidencePreservingReducerProvider": "provider-id",
7
+ "evidencePreservingReducerModel": "model-id",
8
+ "onlineContextCompact": false,
9
+ "cacheWriteReadRatio": 12.5
10
+ }