@herbertgao/pi-extensions 2026.8.3 โ†’ 2026.8.5

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 (408) hide show
  1. package/README.md +45 -4
  2. package/examples/pi-footer.json +275 -0
  3. package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +10 -2
  4. package/node_modules/@herbertgao/pi-cc-extensions/README.md +10 -2
  5. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +24 -0
  6. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +91 -1
  7. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +7 -3
  8. package/node_modules/@herbertgao/pi-cc-extensions/extensions/index.ts +7 -6
  9. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +21 -12
  10. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +4 -5
  11. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/markdown-enhance.ts +5 -8
  12. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +22 -12
  13. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/result.ts +2 -4
  14. package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
  15. package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +8 -0
  16. package/node_modules/@herbertgao/pi-subagents/package.json +8 -4
  17. package/node_modules/@herbertgao/pi-subagents/src/agent-color.ts +72 -67
  18. package/node_modules/@herbertgao/pi-subagents/src/agent-file-toggle.ts +255 -0
  19. package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +191 -3
  20. package/node_modules/@herbertgao/pi-subagents/src/agent-runner.ts +15 -2
  21. package/node_modules/@herbertgao/pi-subagents/src/index.ts +289 -113
  22. package/node_modules/@herbertgao/pi-subagents/src/output-file.ts +24 -1
  23. package/node_modules/@herbertgao/pi-subagents/src/ui/agent-widget.ts +24 -2
  24. package/node_modules/@herbertgao/pi-subagents/src/ui/schedule-menu.ts +9 -8
  25. package/node_modules/@herbertgao/pi-subagents/src/ui/select-item.ts +48 -0
  26. package/node_modules/@juicesharp/rpiv-ask-user-question/docs/keyboard.md +7 -0
  27. package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +2 -2
  28. package/node_modules/@juicesharp/rpiv-ask-user-question/state/build-questionnaire.ts +7 -0
  29. package/node_modules/@juicesharp/rpiv-ask-user-question/state/key-router.ts +16 -5
  30. package/node_modules/@juicesharp/rpiv-ask-user-question/state/questionnaire-session.ts +4 -2
  31. package/node_modules/@narumitw/pi-btw/README.md +8 -7
  32. package/node_modules/@narumitw/pi-btw/package.json +2 -2
  33. package/node_modules/@narumitw/pi-btw/src/menu.ts +1 -0
  34. package/node_modules/pi-footer/CHANGELOG.md +145 -0
  35. package/node_modules/pi-footer/LICENSE +21 -0
  36. package/node_modules/pi-footer/README.md +354 -0
  37. package/node_modules/pi-footer/package.json +68 -0
  38. package/node_modules/pi-footer/src/cache.ts +106 -0
  39. package/node_modules/pi-footer/src/colors.ts +237 -0
  40. package/node_modules/pi-footer/src/config.ts +202 -0
  41. package/node_modules/pi-footer/src/event-widgets.ts +41 -0
  42. package/node_modules/pi-footer/src/extension-statuses.ts +102 -0
  43. package/node_modules/pi-footer/src/git.ts +135 -0
  44. package/node_modules/pi-footer/src/index.ts +268 -0
  45. package/node_modules/pi-footer/src/metrics.ts +141 -0
  46. package/node_modules/pi-footer/src/presets.ts +383 -0
  47. package/node_modules/pi-footer/src/render.ts +114 -0
  48. package/node_modules/pi-footer/src/separators.ts +52 -0
  49. package/node_modules/pi-footer/src/types.ts +122 -0
  50. package/node_modules/pi-footer/src/ui/color-level-confirm.ts +22 -0
  51. package/node_modules/pi-footer/src/ui/color-options.ts +195 -0
  52. package/node_modules/pi-footer/src/ui/config-lifecycle.ts +61 -0
  53. package/node_modules/pi-footer/src/ui/edit-colors.ts +13 -0
  54. package/node_modules/pi-footer/src/ui/events.ts +35 -0
  55. package/node_modules/pi-footer/src/ui/extension-status-picker.ts +60 -0
  56. package/node_modules/pi-footer/src/ui/extension-statuses.ts +73 -0
  57. package/node_modules/pi-footer/src/ui/fields.ts +252 -0
  58. package/node_modules/pi-footer/src/ui/global-menu.ts +126 -0
  59. package/node_modules/pi-footer/src/ui/helpers.ts +44 -0
  60. package/node_modules/pi-footer/src/ui/layout.ts +17 -0
  61. package/node_modules/pi-footer/src/ui/line-list.ts +19 -0
  62. package/node_modules/pi-footer/src/ui/model.ts +64 -0
  63. package/node_modules/pi-footer/src/ui/navigation.ts +29 -0
  64. package/node_modules/pi-footer/src/ui/option-edit.ts +93 -0
  65. package/node_modules/pi-footer/src/ui/overlay-render.ts +103 -0
  66. package/node_modules/pi-footer/src/ui/screen-context.ts +18 -0
  67. package/node_modules/pi-footer/src/ui/screen-controller.ts +27 -0
  68. package/node_modules/pi-footer/src/ui/screen-render.ts +32 -0
  69. package/node_modules/pi-footer/src/ui/screen-state.ts +20 -0
  70. package/node_modules/pi-footer/src/ui/screen.ts +243 -0
  71. package/node_modules/pi-footer/src/ui/screens/add-widget.ts +92 -0
  72. package/node_modules/pi-footer/src/ui/screens/confirm-exit.ts +52 -0
  73. package/node_modules/pi-footer/src/ui/screens/controller.ts +12 -0
  74. package/node_modules/pi-footer/src/ui/screens/edit-colors.ts +68 -0
  75. package/node_modules/pi-footer/src/ui/screens/edit-widget.ts +115 -0
  76. package/node_modules/pi-footer/src/ui/screens/extension-status-row.ts +61 -0
  77. package/node_modules/pi-footer/src/ui/screens/global.ts +75 -0
  78. package/node_modules/pi-footer/src/ui/screens/line-list.ts +108 -0
  79. package/node_modules/pi-footer/src/ui/screens/main.ts +99 -0
  80. package/node_modules/pi-footer/src/ui/screens/terminal.ts +121 -0
  81. package/node_modules/pi-footer/src/ui/screens/widget-list.ts +154 -0
  82. package/node_modules/pi-footer/src/ui/terminal-menu.ts +32 -0
  83. package/node_modules/pi-footer/src/ui/theme.ts +48 -0
  84. package/node_modules/pi-footer/src/ui/title-bar.ts +100 -0
  85. package/node_modules/pi-footer/src/ui/widget-actions.ts +76 -0
  86. package/node_modules/pi-footer/src/ui.ts +66 -0
  87. package/node_modules/pi-footer/src/widgets/context.ts +28 -0
  88. package/node_modules/pi-footer/src/widgets/core/active-tools.ts +17 -0
  89. package/node_modules/pi-footer/src/widgets/core/context-window.ts +24 -0
  90. package/node_modules/pi-footer/src/widgets/core/cwd-basename.ts +19 -0
  91. package/node_modules/pi-footer/src/widgets/core/cwd.ts +108 -0
  92. package/node_modules/pi-footer/src/widgets/core/event.ts +34 -0
  93. package/node_modules/pi-footer/src/widgets/core/external-status.ts +102 -0
  94. package/node_modules/pi-footer/src/widgets/core/model-provider.ts +20 -0
  95. package/node_modules/pi-footer/src/widgets/core/model.ts +35 -0
  96. package/node_modules/pi-footer/src/widgets/core/provider.ts +17 -0
  97. package/node_modules/pi-footer/src/widgets/core/session-name.ts +17 -0
  98. package/node_modules/pi-footer/src/widgets/core/text-verbosity.ts +17 -0
  99. package/node_modules/pi-footer/src/widgets/core/thinking-level.ts +17 -0
  100. package/node_modules/pi-footer/src/widgets/git/ahead-behind.ts +17 -0
  101. package/node_modules/pi-footer/src/widgets/git/branch.ts +81 -0
  102. package/node_modules/pi-footer/src/widgets/git/clean.ts +19 -0
  103. package/node_modules/pi-footer/src/widgets/git/deletions.ts +17 -0
  104. package/node_modules/pi-footer/src/widgets/git/diff.ts +38 -0
  105. package/node_modules/pi-footer/src/widgets/git/insertions.ts +17 -0
  106. package/node_modules/pi-footer/src/widgets/git/remote.ts +17 -0
  107. package/node_modules/pi-footer/src/widgets/git/root.ts +17 -0
  108. package/node_modules/pi-footer/src/widgets/git/sha.ts +17 -0
  109. package/node_modules/pi-footer/src/widgets/git/staged.ts +17 -0
  110. package/node_modules/pi-footer/src/widgets/git/status.ts +19 -0
  111. package/node_modules/pi-footer/src/widgets/git/unstaged.ts +17 -0
  112. package/node_modules/pi-footer/src/widgets/git/untracked.ts +17 -0
  113. package/node_modules/pi-footer/src/widgets/instance.ts +118 -0
  114. package/node_modules/pi-footer/src/widgets/layout/custom-text.ts +18 -0
  115. package/node_modules/pi-footer/src/widgets/layout/flex-separator.ts +32 -0
  116. package/node_modules/pi-footer/src/widgets/layout/separator.ts +57 -0
  117. package/node_modules/pi-footer/src/widgets/layout/spacer.ts +31 -0
  118. package/node_modules/pi-footer/src/widgets/options.ts +122 -0
  119. package/node_modules/pi-footer/src/widgets/project/runtime.ts +361 -0
  120. package/node_modules/pi-footer/src/widgets/registry.ts +223 -0
  121. package/node_modules/pi-footer/src/widgets/session/assistant-messages.ts +17 -0
  122. package/node_modules/pi-footer/src/widgets/session/compactions.ts +17 -0
  123. package/node_modules/pi-footer/src/widgets/session/elapsed.ts +18 -0
  124. package/node_modules/pi-footer/src/widgets/session/last-activity.ts +18 -0
  125. package/node_modules/pi-footer/src/widgets/session/messages.ts +19 -0
  126. package/node_modules/pi-footer/src/widgets/session/session-id.ts +17 -0
  127. package/node_modules/pi-footer/src/widgets/session/session-start.ts +18 -0
  128. package/node_modules/pi-footer/src/widgets/session/tool-results.ts +17 -0
  129. package/node_modules/pi-footer/src/widgets/session/total-messages.ts +19 -0
  130. package/node_modules/pi-footer/src/widgets/session/total-time.ts +18 -0
  131. package/node_modules/pi-footer/src/widgets/session/user-messages.ts +17 -0
  132. package/node_modules/pi-footer/src/widgets/store.ts +26 -0
  133. package/node_modules/pi-footer/src/widgets/tokens/cache-hit-rate.ts +55 -0
  134. package/node_modules/pi-footer/src/widgets/tokens/cache-read.ts +18 -0
  135. package/node_modules/pi-footer/src/widgets/tokens/cache-write.ts +18 -0
  136. package/node_modules/pi-footer/src/widgets/tokens/context-bar.ts +108 -0
  137. package/node_modules/pi-footer/src/widgets/tokens/context-length.ts +26 -0
  138. package/node_modules/pi-footer/src/widgets/tokens/context-remaining.ts +29 -0
  139. package/node_modules/pi-footer/src/widgets/tokens/context.ts +29 -0
  140. package/node_modules/pi-footer/src/widgets/tokens/cost.ts +51 -0
  141. package/node_modules/pi-footer/src/widgets/tokens/input-speed.ts +25 -0
  142. package/node_modules/pi-footer/src/widgets/tokens/input-tokens.ts +18 -0
  143. package/node_modules/pi-footer/src/widgets/tokens/output-speed.ts +25 -0
  144. package/node_modules/pi-footer/src/widgets/tokens/output-tokens.ts +18 -0
  145. package/node_modules/pi-footer/src/widgets/tokens/tokens.ts +20 -0
  146. package/node_modules/pi-footer/src/widgets/tokens/total-speed.ts +25 -0
  147. package/node_modules/pi-footer/src/widgets/tokens/total-tokens.ts +18 -0
  148. package/node_modules/pi-footer/src/widgets/types.ts +181 -0
  149. package/node_modules/pi-footer/src/widgets/utils/colors.ts +11 -0
  150. package/node_modules/pi-footer/src/widgets/utils/context.ts +112 -0
  151. package/node_modules/pi-footer/src/widgets/utils/session.ts +19 -0
  152. package/node_modules/pi-footer/src/widgets/utils/token-format.ts +78 -0
  153. package/node_modules/pi-lens/CHANGELOG.md +2440 -954
  154. package/node_modules/pi-lens/README.md +13 -0
  155. package/node_modules/pi-lens/dist/clients/actionable-warnings.js +73 -18
  156. package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +21 -4
  157. package/node_modules/pi-lens/dist/clients/ast-grep-client.js +68 -16
  158. package/node_modules/pi-lens/dist/clients/ast-grep-types.js +0 -1
  159. package/node_modules/pi-lens/dist/clients/ast-grep-yaml-synth.js +37 -10
  160. package/node_modules/pi-lens/dist/clients/atomic-write-staging.js +63 -0
  161. package/node_modules/pi-lens/dist/clients/atomic-write.js +114 -14
  162. package/node_modules/pi-lens/dist/clients/bash-file-access.js +193 -23
  163. package/node_modules/pi-lens/dist/clients/biome-client.js +29 -25
  164. package/node_modules/pi-lens/dist/clients/bootstrap.js +11 -2
  165. package/node_modules/pi-lens/dist/clients/bounded-cache.js +34 -0
  166. package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +192 -0
  167. package/node_modules/pi-lens/dist/clients/bus-publish.js +10 -3
  168. package/node_modules/pi-lens/dist/clients/cache/rule-cache.js +47 -5
  169. package/node_modules/pi-lens/dist/clients/cache-manager.js +97 -9
  170. package/node_modules/pi-lens/dist/clients/cache-observability.js +301 -14
  171. package/node_modules/pi-lens/dist/clients/call-graph.js +449 -117
  172. package/node_modules/pi-lens/dist/clients/child-unref.js +85 -0
  173. package/node_modules/pi-lens/dist/clients/codebase-model.js +52 -23
  174. package/node_modules/pi-lens/dist/clients/collateral-test-role.js +40 -0
  175. package/node_modules/pi-lens/dist/clients/complexity-client.js +2 -1
  176. package/node_modules/pi-lens/dist/clients/console-guard-install.js +14 -0
  177. package/node_modules/pi-lens/dist/clients/cooperative-budget.js +42 -0
  178. package/node_modules/pi-lens/dist/clients/dead-code-client.js +2 -1
  179. package/node_modules/pi-lens/dist/clients/debug-handles.js +206 -0
  180. package/node_modules/pi-lens/dist/clients/debug-heap.js +167 -0
  181. package/node_modules/pi-lens/dist/clients/degradation-ledger.js +153 -0
  182. package/node_modules/pi-lens/dist/clients/dependency-checker.js +347 -75
  183. package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +61 -11
  184. package/node_modules/pi-lens/dist/clients/diagnostics-publish.js +10 -3
  185. package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +63 -20
  186. package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +23 -7
  187. package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +8 -18
  188. package/node_modules/pi-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +8 -5
  189. package/node_modules/pi-lens/dist/clients/dispatch/indent-detect.js +35 -0
  190. package/node_modules/pi-lens/dist/clients/dispatch/inline-suppressions.js +17 -8
  191. package/node_modules/pi-lens/dist/clients/dispatch/integration.js +1085 -681
  192. package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +14 -0
  193. package/node_modules/pi-lens/dist/clients/dispatch/plan.js +11 -1
  194. package/node_modules/pi-lens/dist/clients/dispatch/rule-id-normalize.js +50 -0
  195. package/node_modules/pi-lens/dist/clients/dispatch/rule-policy.js +135 -0
  196. package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +23 -5
  197. package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +5 -9
  198. package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +3 -2
  199. package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +2 -1
  200. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +154 -0
  201. package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +3 -2
  202. package/node_modules/pi-lens/dist/clients/dispatch/runners/index.js +5 -1
  203. package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +14 -6
  204. package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +4 -9
  205. package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +9 -5
  206. package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +4 -8
  207. package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +2 -3
  208. package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +2 -3
  209. package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.js +2 -1
  210. package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +2 -1
  211. package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +163 -0
  212. package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +37 -5
  213. package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +3 -1
  214. package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +13 -7
  215. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +3 -0
  216. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +277 -26
  217. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +22 -0
  218. package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +5 -4
  219. package/node_modules/pi-lens/dist/clients/disposition-publish.js +10 -3
  220. package/node_modules/pi-lens/dist/clients/durable-store.js +97 -0
  221. package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +94 -3
  222. package/node_modules/pi-lens/dist/clients/extension-log.js +139 -0
  223. package/node_modules/pi-lens/dist/clients/extension-mode.js +73 -0
  224. package/node_modules/pi-lens/dist/clients/file-kinds.js +57 -0
  225. package/node_modules/pi-lens/dist/clients/file-role.js +18 -3
  226. package/node_modules/pi-lens/dist/clients/file-utils.js +56 -34
  227. package/node_modules/pi-lens/dist/clients/format-events-publish.js +16 -3
  228. package/node_modules/pi-lens/dist/clients/format-service.js +24 -8
  229. package/node_modules/pi-lens/dist/clients/formatters-lazy.js +8 -0
  230. package/node_modules/pi-lens/dist/clients/formatters.js +358 -61
  231. package/node_modules/pi-lens/dist/clients/generated-artifacts.js +148 -15
  232. package/node_modules/pi-lens/dist/clients/git-guard.js +681 -11
  233. package/node_modules/pi-lens/dist/clients/git-tracked-ignore.js +4 -0
  234. package/node_modules/pi-lens/dist/clients/go-client.js +2 -1
  235. package/node_modules/pi-lens/dist/clients/govulncheck-client.js +8 -0
  236. package/node_modules/pi-lens/dist/clients/grammar-source.js +12 -4
  237. package/node_modules/pi-lens/dist/clients/gzip-stage-write.js +21 -3
  238. package/node_modules/pi-lens/dist/clients/host-ports.js +31 -0
  239. package/node_modules/pi-lens/dist/clients/installer/index.js +390 -99
  240. package/node_modules/pi-lens/dist/clients/instance-reaper.js +142 -172
  241. package/node_modules/pi-lens/dist/clients/jscpd-client.js +31 -54
  242. package/node_modules/pi-lens/dist/clients/knip-client.js +15 -36
  243. package/node_modules/pi-lens/dist/clients/language-policy.js +14 -2
  244. package/node_modules/pi-lens/dist/clients/language-profile.js +13 -7
  245. package/node_modules/pi-lens/dist/clients/latency-logger.js +23 -1
  246. package/node_modules/pi-lens/dist/clients/lens-config.js +12 -1
  247. package/node_modules/pi-lens/dist/clients/lens-engine.js +86 -17
  248. package/node_modules/pi-lens/dist/clients/lens-events.js +27 -4
  249. package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +8 -0
  250. package/node_modules/pi-lens/dist/clients/lens-map.js +94 -19
  251. package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +30 -0
  252. package/node_modules/pi-lens/dist/clients/log-cleanup.js +2 -1
  253. package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +1 -1
  254. package/node_modules/pi-lens/dist/clients/lsp/client.js +493 -48
  255. package/node_modules/pi-lens/dist/clients/lsp/config.js +13 -2
  256. package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +86 -0
  257. package/node_modules/pi-lens/dist/clients/lsp/edits.js +1012 -121
  258. package/node_modules/pi-lens/dist/clients/lsp/index.js +1807 -780
  259. package/node_modules/pi-lens/dist/clients/lsp/launch.js +32 -26
  260. package/node_modules/pi-lens/dist/clients/lsp/path-utils.js +1 -1
  261. package/node_modules/pi-lens/dist/clients/lsp/ruby-drive-dirs.js +83 -0
  262. package/node_modules/pi-lens/dist/clients/lsp/server.js +196 -32
  263. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +28 -4
  264. package/node_modules/pi-lens/dist/clients/lsp-lazy.js +8 -0
  265. package/node_modules/pi-lens/dist/clients/lsp-mutation.js +248 -0
  266. package/node_modules/pi-lens/dist/clients/mcp/analyze.js +123 -32
  267. package/node_modules/pi-lens/dist/clients/mcp/ipc.js +157 -24
  268. package/node_modules/pi-lens/dist/clients/mcp/session.js +216 -8
  269. package/node_modules/pi-lens/dist/clients/memory-sampler.js +115 -0
  270. package/node_modules/pi-lens/dist/clients/metrics-client.js +2 -1
  271. package/node_modules/pi-lens/dist/clients/metrics-history.js +2 -1
  272. package/node_modules/pi-lens/dist/clients/module-report-lsp.js +5 -0
  273. package/node_modules/pi-lens/dist/clients/module-report.js +168 -3
  274. package/node_modules/pi-lens/dist/clients/ndjson-logger.js +319 -118
  275. package/node_modules/pi-lens/dist/clients/opengrep-client.js +1 -1
  276. package/node_modules/pi-lens/dist/clients/partial-edit-apply.js +120 -5
  277. package/node_modules/pi-lens/dist/clients/path-utils.js +110 -9
  278. package/node_modules/pi-lens/dist/clients/pipeline.js +47 -13
  279. package/node_modules/pi-lens/dist/clients/print-mode.js +21 -0
  280. package/node_modules/pi-lens/dist/clients/project-changes.js +40 -0
  281. package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +3 -2
  282. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +8 -0
  283. package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +21 -1
  284. package/node_modules/pi-lens/dist/clients/project-lens-config.js +86 -9
  285. package/node_modules/pi-lens/dist/clients/project-report.js +27 -13
  286. package/node_modules/pi-lens/dist/clients/project-snapshot.js +175 -20
  287. package/node_modules/pi-lens/dist/clients/project-trust.js +181 -0
  288. package/node_modules/pi-lens/dist/clients/quiet-window.js +18 -4
  289. package/node_modules/pi-lens/dist/clients/read-bridge.js +147 -0
  290. package/node_modules/pi-lens/dist/clients/read-guard-logger.js +159 -1
  291. package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +150 -29
  292. package/node_modules/pi-lens/dist/clients/read-guard.js +185 -4
  293. package/node_modules/pi-lens/dist/clients/resource-sampler.js +70 -84
  294. package/node_modules/pi-lens/dist/clients/review-graph/builder.js +1122 -221
  295. package/node_modules/pi-lens/dist/clients/review-graph/git-identity.js +2 -1
  296. package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +21 -10
  297. package/node_modules/pi-lens/dist/clients/review-graph/symbol-id.js +46 -0
  298. package/node_modules/pi-lens/dist/clients/review-graph/tsconfig-paths.js +57 -6
  299. package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +51 -3
  300. package/node_modules/pi-lens/dist/clients/review-graph-logger.js +30 -1
  301. package/node_modules/pi-lens/dist/clients/ruff-client.js +27 -44
  302. package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +107 -73
  303. package/node_modules/pi-lens/dist/clients/runtime-context.js +36 -12
  304. package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +74 -6
  305. package/node_modules/pi-lens/dist/clients/runtime-session.js +405 -117
  306. package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +71 -48
  307. package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +218 -23
  308. package/node_modules/pi-lens/dist/clients/runtime-turn.js +237 -64
  309. package/node_modules/pi-lens/dist/clients/rust-client.js +2 -1
  310. package/node_modules/pi-lens/dist/clients/safe-spawn.js +777 -62
  311. package/node_modules/pi-lens/dist/clients/security-scan-client.js +2 -1
  312. package/node_modules/pi-lens/dist/clients/session-state-store.js +3 -2
  313. package/node_modules/pi-lens/dist/clients/sg-runner.js +284 -174
  314. package/node_modules/pi-lens/dist/clients/slow-fs.js +2 -1
  315. package/node_modules/pi-lens/dist/clients/smells-rollup.js +224 -0
  316. package/node_modules/pi-lens/dist/clients/source-filter.js +184 -20
  317. package/node_modules/pi-lens/dist/clients/source-walker.js +66 -10
  318. package/node_modules/pi-lens/dist/clients/startup-scan.js +15 -16
  319. package/node_modules/pi-lens/dist/clients/startup-timing.js +1 -1
  320. package/node_modules/pi-lens/dist/clients/test-runner-client.js +38 -8
  321. package/node_modules/pi-lens/dist/clients/tool-event.js +35 -0
  322. package/node_modules/pi-lens/dist/clients/tool-policy.js +388 -39
  323. package/node_modules/pi-lens/dist/clients/tool-render.js +155 -0
  324. package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +6 -1
  325. package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +419 -50
  326. package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +21 -0
  327. package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +7 -1
  328. package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +7 -2
  329. package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +44 -7
  330. package/node_modules/pi-lens/dist/clients/user-notify.js +51 -0
  331. package/node_modules/pi-lens/dist/clients/vanished-instance-marker.js +57 -0
  332. package/node_modules/pi-lens/dist/clients/warm-attach.js +33 -13
  333. package/node_modules/pi-lens/dist/clients/widget-state.js +300 -43
  334. package/node_modules/pi-lens/dist/clients/word-index.js +391 -64
  335. package/node_modules/pi-lens/dist/clients/workspace-topology.js +89 -6
  336. package/node_modules/pi-lens/dist/index.js +49361 -36888
  337. package/node_modules/pi-lens/dist/mcp/analyze-cli.js +182 -29
  338. package/node_modules/pi-lens/dist/mcp/server.js +211 -44
  339. package/node_modules/pi-lens/dist/tools/ast-grep-search.js +93 -27
  340. package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +200 -36
  341. package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +153 -40
  342. package/node_modules/pi-lens/dist/tools/lsp-navigation.js +46 -3
  343. package/node_modules/pi-lens/dist/tools/module-report.js +9 -0
  344. package/node_modules/pi-lens/docs/agent-guide.md +2 -2
  345. package/node_modules/pi-lens/docs/agent-tools.md +21 -10
  346. package/node_modules/pi-lens/docs/analysisall.md +192 -0
  347. package/node_modules/pi-lens/docs/api-ports-inventory.md +165 -0
  348. package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +5 -2
  349. package/node_modules/pi-lens/docs/durable-store-audit-1202.md +32 -0
  350. package/node_modules/pi-lens/docs/environment-variables.md +44 -0
  351. package/node_modules/pi-lens/docs/fable.md +27 -0
  352. package/node_modules/pi-lens/docs/features.md +31 -2
  353. package/node_modules/pi-lens/docs/globalconfig.md +45 -1
  354. package/node_modules/pi-lens/docs/language-coverage.md +4 -3
  355. package/node_modules/pi-lens/docs/lsp-capability-matrix.md +2 -2
  356. package/node_modules/pi-lens/docs/mcp.md +37 -4
  357. package/node_modules/pi-lens/docs/servercapabilities.md +3 -3
  358. package/node_modules/pi-lens/docs/settings.md +12 -1
  359. package/node_modules/pi-lens/docs/tools.md +4 -1
  360. package/node_modules/pi-lens/docs/usage.md +18 -0
  361. package/node_modules/pi-lens/package.json +10 -10
  362. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-bare-except-test.yml +49 -0
  363. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-bare-host-path-in-win32-branch-test.yml +87 -0
  364. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-nested-links-test.yml +11 -1
  365. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-raw-json-store-write-test.yml +17 -0
  366. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-win32-isabsolute-for-qualification-test.yml +16 -0
  367. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-except.yml +3 -15
  368. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-host-path-in-win32-branch.yml +25 -0
  369. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-nested-links.yml +7 -0
  370. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-raw-json-store-write.yml +30 -0
  371. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-win32-isabsolute-for-qualification.yml +23 -0
  372. package/node_modules/pi-lens/rules/tree-sitter-queries/tsx/no-nested-links.yml +4 -6
  373. package/node_modules/pi-lens/rules/tree-sitter-queries/typescript/duplicate-function-arg.yml +2 -2
  374. package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +55 -2
  375. package/node_modules/pi-mcp-adapter/CHANGELOG.md +25 -0
  376. package/node_modules/pi-mcp-adapter/README.md +34 -3
  377. package/node_modules/pi-mcp-adapter/agent-plugin-loader.ts +1 -1
  378. package/node_modules/pi-mcp-adapter/commands.ts +15 -7
  379. package/node_modules/pi-mcp-adapter/direct-tools.ts +54 -7
  380. package/node_modules/pi-mcp-adapter/host-html-template.ts +0 -8
  381. package/node_modules/pi-mcp-adapter/index.ts +8 -3
  382. package/node_modules/pi-mcp-adapter/init.ts +29 -5
  383. package/node_modules/pi-mcp-adapter/lifecycle.ts +0 -4
  384. package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +1 -2
  385. package/node_modules/pi-mcp-adapter/mcp-auth.ts +60 -2
  386. package/node_modules/pi-mcp-adapter/mcp-panel.ts +45 -9
  387. package/node_modules/pi-mcp-adapter/mcp-script-worker.mjs +22 -20
  388. package/node_modules/pi-mcp-adapter/metadata-cache.ts +27 -4
  389. package/node_modules/pi-mcp-adapter/npx-resolver.ts +81 -26
  390. package/node_modules/pi-mcp-adapter/package.json +3 -3
  391. package/node_modules/pi-mcp-adapter/proxy-modes.ts +108 -26
  392. package/node_modules/pi-mcp-adapter/search-ranking.ts +86 -7
  393. package/node_modules/pi-mcp-adapter/server-manager.ts +36 -7
  394. package/node_modules/pi-mcp-adapter/session-recovery.ts +8 -2
  395. package/node_modules/pi-mcp-adapter/tool-approval.ts +48 -7
  396. package/node_modules/pi-mcp-adapter/tool-metadata.ts +42 -4
  397. package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +138 -12
  398. package/node_modules/pi-mcp-adapter/types.ts +93 -27
  399. package/node_modules/pi-mcp-adapter/ui-server.ts +20 -1
  400. package/package.json +17 -13
  401. package/node_modules/pi-lens/dist/clients/ast-grep-parser.js +0 -86
  402. package/node_modules/pi-lens/dist/clients/lsp/interactive-install.js +0 -367
  403. package/node_modules/pi-lens/dist/clients/lsp/lsp-index.js +0 -10
  404. package/node_modules/pi-lens/dist/clients/lsp/server-strategies.js +0 -5
  405. package/node_modules/pi-lens/dist/clients/project-metadata.js +0 -690
  406. package/node_modules/pi-lens/dist/clients/source-groups.js +0 -96
  407. package/node_modules/pi-lens/dist/clients/startup-marker.js +0 -6
  408. package/node_modules/pi-lens/dist/clients/types.js +0 -11
@@ -1,690 +0,0 @@
1
- /**
2
- * Project Metadata Detection for pi-lens
3
- *
4
- * Extracts project configuration from common config files:
5
- * - package.json (Node.js/npm/pnpm/yarn/bun)
6
- * - pyproject.toml (Python)
7
- * - Cargo.toml (Rust)
8
- * - go.mod (Go)
9
- * - composer.json (PHP)
10
- * - Gemfile (Ruby)
11
- */
12
- import * as fs from "node:fs";
13
- import * as path from "node:path";
14
- import { detectNodePackageManager, formatRunScript, } from "./package-manager.js";
15
- // --- Detection Functions ---
16
- /**
17
- * Detect project metadata from a target directory.
18
- * Reads common config files and extracts structured information.
19
- */
20
- export function detectProjectMetadata(targetPath) {
21
- const metadata = {
22
- type: "unknown",
23
- scripts: {},
24
- languages: [],
25
- hasTests: false,
26
- hasLinting: false,
27
- hasFormatting: false,
28
- hasTypeScript: false,
29
- configFiles: [],
30
- };
31
- // Check for Node.js project
32
- const nodeMeta = detectNodeProject(targetPath);
33
- if (nodeMeta) {
34
- Object.assign(metadata, nodeMeta);
35
- }
36
- // Check for Python project
37
- const pythonMeta = detectPythonProject(targetPath);
38
- if (pythonMeta && metadata.type === "unknown") {
39
- Object.assign(metadata, pythonMeta);
40
- }
41
- // Check for Rust project
42
- const rustMeta = detectRustProject(targetPath);
43
- if (rustMeta && metadata.type === "unknown") {
44
- Object.assign(metadata, rustMeta);
45
- }
46
- // Check for Go project
47
- const goMeta = detectGoProject(targetPath);
48
- if (goMeta && metadata.type === "unknown") {
49
- Object.assign(metadata, goMeta);
50
- }
51
- // Check for PHP project
52
- const phpMeta = detectPhpProject(targetPath);
53
- if (phpMeta && metadata.type === "unknown") {
54
- Object.assign(metadata, phpMeta);
55
- }
56
- // Check for Ruby project
57
- const rubyMeta = detectRubyProject(targetPath);
58
- if (rubyMeta && metadata.type === "unknown") {
59
- Object.assign(metadata, rubyMeta);
60
- }
61
- // Check for Java project
62
- const javaMeta = detectJavaProject(targetPath);
63
- if (javaMeta && metadata.type === "unknown") {
64
- Object.assign(metadata, javaMeta);
65
- }
66
- // Check for Kotlin project
67
- const kotlinMeta = detectKotlinProject(targetPath);
68
- if (kotlinMeta && metadata.type === "unknown") {
69
- Object.assign(metadata, kotlinMeta);
70
- }
71
- // Check for C# project
72
- const csharpMeta = detectCsharpProject(targetPath);
73
- if (csharpMeta && metadata.type === "unknown") {
74
- Object.assign(metadata, csharpMeta);
75
- }
76
- // Check for Dart project
77
- const dartMeta = detectDartProject(targetPath);
78
- if (dartMeta && metadata.type === "unknown") {
79
- Object.assign(metadata, dartMeta);
80
- }
81
- // Check for Gleam project
82
- const gleamMeta = detectGleamProject(targetPath);
83
- if (gleamMeta && metadata.type === "unknown") {
84
- Object.assign(metadata, gleamMeta);
85
- }
86
- // Check for Zig project
87
- const zigMeta = detectZigProject(targetPath);
88
- if (zigMeta && metadata.type === "unknown") {
89
- Object.assign(metadata, zigMeta);
90
- }
91
- // Check for Elixir project
92
- const elixirMeta = detectElixirProject(targetPath);
93
- if (elixirMeta && metadata.type === "unknown") {
94
- Object.assign(metadata, elixirMeta);
95
- }
96
- // Check for C/C++ project
97
- const cppMeta = detectCppProject(targetPath);
98
- if (cppMeta && metadata.type === "unknown") {
99
- Object.assign(metadata, cppMeta);
100
- }
101
- // Multi-project detection: if multiple types found
102
- const types = [nodeMeta, pythonMeta, rustMeta, goMeta, phpMeta, rubyMeta,
103
- javaMeta, kotlinMeta, csharpMeta, dartMeta, gleamMeta, zigMeta, elixirMeta, cppMeta]
104
- .filter(Boolean)
105
- .map(m => m.type);
106
- if (types.length > 1) {
107
- metadata.type = "multi";
108
- metadata.languages = [...new Set(types)];
109
- }
110
- return metadata;
111
- }
112
- /**
113
- * Detect Node.js project from package.json and lockfiles
114
- */
115
- function detectNodeProject(targetPath) {
116
- const packageJsonPath = path.join(targetPath, "package.json");
117
- if (!fs.existsSync(packageJsonPath)) {
118
- return null;
119
- }
120
- let packageJson;
121
- try {
122
- packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
123
- }
124
- catch {
125
- return null;
126
- }
127
- const metadata = {
128
- type: "node",
129
- name: typeof packageJson.name === "string" ? packageJson.name : undefined,
130
- version: typeof packageJson.version === "string" ? packageJson.version : undefined,
131
- packageManager: detectNodePackageManager(targetPath),
132
- scripts: typeof packageJson.scripts === "object" && packageJson.scripts !== null
133
- ? packageJson.scripts
134
- : {},
135
- languages: ["javascript"],
136
- hasTests: false,
137
- hasLinting: false,
138
- hasFormatting: false,
139
- hasTypeScript: fs.existsSync(path.join(targetPath, "tsconfig.json")),
140
- configFiles: ["package.json"],
141
- };
142
- // Detect TypeScript
143
- if (metadata.hasTypeScript) {
144
- metadata.languages.push("typescript");
145
- metadata.configFiles.push("tsconfig.json");
146
- }
147
- // Detect tests from scripts or config files
148
- const scripts = Object.keys(metadata.scripts).join(" ").toLowerCase();
149
- if (scripts.includes("test") || scripts.includes("spec")) {
150
- metadata.hasTests = true;
151
- }
152
- // Detect test frameworks from dependencies
153
- const allDeps = {
154
- ...(packageJson.dependencies || {}),
155
- ...(packageJson.devDependencies || {}),
156
- };
157
- if (allDeps["vitest"]) {
158
- metadata.hasTests = true;
159
- metadata.testFramework = "vitest";
160
- }
161
- else if (allDeps["jest"]) {
162
- metadata.hasTests = true;
163
- metadata.testFramework = "jest";
164
- }
165
- else if (allDeps["mocha"]) {
166
- metadata.hasTests = true;
167
- metadata.testFramework = "mocha";
168
- }
169
- else if (allDeps["ava"]) {
170
- metadata.hasTests = true;
171
- metadata.testFramework = "ava";
172
- }
173
- else if (allDeps["tap"]) {
174
- metadata.hasTests = true;
175
- metadata.testFramework = "tap";
176
- }
177
- else if (allDeps["node:test"]) {
178
- metadata.hasTests = true;
179
- metadata.testFramework = "node:test";
180
- }
181
- // Detect linting
182
- if (allDeps["eslint"] || fs.existsSync(path.join(targetPath, ".eslintrc")) ||
183
- fs.existsSync(path.join(targetPath, ".eslintrc.js")) ||
184
- fs.existsSync(path.join(targetPath, "eslint.config.js")) ||
185
- fs.existsSync(path.join(targetPath, "eslint.config.mjs"))) {
186
- metadata.hasLinting = true;
187
- metadata.linter = "eslint";
188
- metadata.configFiles.push("eslint config");
189
- }
190
- if (allDeps["@biomejs/biome"] || fs.existsSync(path.join(targetPath, "biome.json"))) {
191
- metadata.hasLinting = true;
192
- metadata.linter = metadata.linter ? `${metadata.linter}, biome` : "biome";
193
- metadata.configFiles.push("biome.json");
194
- }
195
- // Detect formatting
196
- if (allDeps["prettier"] || fs.existsSync(path.join(targetPath, ".prettierrc")) ||
197
- fs.existsSync(path.join(targetPath, ".prettierrc.json"))) {
198
- metadata.hasFormatting = true;
199
- metadata.formatter = metadata.formatter ? `${metadata.formatter}, prettier` : "prettier";
200
- metadata.configFiles.push("prettier config");
201
- }
202
- if (allDeps["@biomejs/biome"]) {
203
- metadata.hasFormatting = true;
204
- metadata.formatter = metadata.formatter ? `${metadata.formatter}, biome` : "biome";
205
- }
206
- return metadata;
207
- }
208
- /**
209
- * Detect Python project from pyproject.toml, setup.py, requirements.txt
210
- */
211
- function detectPythonProject(targetPath) {
212
- const pyprojectPath = path.join(targetPath, "pyproject.toml");
213
- const setupPyPath = path.join(targetPath, "setup.py");
214
- const requirementsPath = path.join(targetPath, "requirements.txt");
215
- if (!fs.existsSync(pyprojectPath) && !fs.existsSync(setupPyPath) && !fs.existsSync(requirementsPath)) {
216
- return null;
217
- }
218
- const metadata = {
219
- type: "python",
220
- packageManager: detectPythonPackageManager(targetPath),
221
- scripts: {},
222
- languages: ["python"],
223
- hasTests: false,
224
- hasLinting: false,
225
- hasFormatting: false,
226
- hasTypeScript: false,
227
- configFiles: [],
228
- };
229
- // Read pyproject.toml if available
230
- if (fs.existsSync(pyprojectPath)) {
231
- metadata.configFiles.push("pyproject.toml");
232
- try {
233
- const content = fs.readFileSync(pyprojectPath, "utf-8");
234
- // Extract project name
235
- const nameMatch = content.match(/\[project\][\s\S]*?name\s*=\s*["']([^"']+)["']/);
236
- if (nameMatch)
237
- metadata.name = nameMatch[1];
238
- // Extract version
239
- const versionMatch = content.match(/\[project\][\s\S]*?version\s*=\s*["']([^"']+)["']/);
240
- if (versionMatch)
241
- metadata.version = versionMatch[1];
242
- // Detect test framework
243
- if (content.includes("pytest") || fs.existsSync(path.join(targetPath, "pytest.ini"))) {
244
- metadata.hasTests = true;
245
- metadata.testFramework = "pytest";
246
- }
247
- // Detect linting
248
- if (content.includes("ruff") || fs.existsSync(path.join(targetPath, "ruff.toml"))) {
249
- metadata.hasLinting = true;
250
- metadata.linter = "ruff";
251
- metadata.hasFormatting = true;
252
- metadata.formatter = "ruff";
253
- }
254
- else if (content.includes("pylint") || content.includes("flake8")) {
255
- metadata.hasLinting = true;
256
- metadata.linter = content.includes("pylint") ? "pylint" : "flake8";
257
- }
258
- }
259
- catch {
260
- // Ignore parse errors
261
- }
262
- }
263
- if (fs.existsSync(setupPyPath))
264
- metadata.configFiles.push("setup.py");
265
- if (fs.existsSync(requirementsPath))
266
- metadata.configFiles.push("requirements.txt");
267
- return metadata;
268
- }
269
- /**
270
- * Detect Python package manager
271
- */
272
- function detectPythonPackageManager(targetPath) {
273
- if (fs.existsSync(path.join(targetPath, "uv.lock"))) {
274
- return "uv";
275
- }
276
- if (fs.existsSync(path.join(targetPath, "poetry.lock"))) {
277
- return "poetry";
278
- }
279
- if (fs.existsSync(path.join(targetPath, "Pipfile.lock")) || fs.existsSync(path.join(targetPath, "Pipfile"))) {
280
- return "pip"; // pipenv uses Pipfile
281
- }
282
- if (fs.existsSync(path.join(targetPath, "requirements.txt"))) {
283
- return "pip";
284
- }
285
- return undefined;
286
- }
287
- /**
288
- * Detect Rust project from Cargo.toml
289
- */
290
- function detectRustProject(targetPath) {
291
- const cargoPath = path.join(targetPath, "Cargo.toml");
292
- if (!fs.existsSync(cargoPath)) {
293
- return null;
294
- }
295
- const metadata = {
296
- type: "rust",
297
- packageManager: "cargo",
298
- scripts: {},
299
- languages: ["rust"],
300
- hasTests: true, // Cargo has built-in test support
301
- hasLinting: false,
302
- hasFormatting: false,
303
- hasTypeScript: false,
304
- configFiles: ["Cargo.toml"],
305
- };
306
- // Read Cargo.toml
307
- try {
308
- const content = fs.readFileSync(cargoPath, "utf-8");
309
- // Extract package name
310
- const nameMatch = content.match(/\[package\][\s\S]*?name\s*=\s*["']([^"']+)["']/);
311
- if (nameMatch)
312
- metadata.name = nameMatch[1];
313
- // Extract version
314
- const versionMatch = content.match(/\[package\][\s\S]*?version\s*=\s*["']([^"']+)["']/);
315
- if (versionMatch)
316
- metadata.version = versionMatch[1];
317
- }
318
- catch {
319
- // Ignore parse errors
320
- }
321
- // Check for clippy (linter)
322
- if (fs.existsSync(path.join(targetPath, ".clippy.toml")) ||
323
- fs.existsSync(path.join(targetPath, "clippy.toml"))) {
324
- metadata.hasLinting = true;
325
- metadata.linter = "clippy";
326
- }
327
- // Check for rustfmt
328
- if (fs.existsSync(path.join(targetPath, ".rustfmt.toml")) ||
329
- fs.existsSync(path.join(targetPath, "rustfmt.toml"))) {
330
- metadata.hasFormatting = true;
331
- metadata.formatter = "rustfmt";
332
- }
333
- return metadata;
334
- }
335
- /**
336
- * Detect Go project from go.mod
337
- */
338
- function detectGoProject(targetPath) {
339
- const goModPath = path.join(targetPath, "go.mod");
340
- if (!fs.existsSync(goModPath)) {
341
- return null;
342
- }
343
- const metadata = {
344
- type: "go",
345
- packageManager: "gomod",
346
- scripts: {},
347
- languages: ["go"],
348
- hasTests: true, // Go has built-in test support
349
- hasLinting: false,
350
- hasFormatting: false,
351
- hasTypeScript: false,
352
- configFiles: ["go.mod"],
353
- };
354
- // Read go.mod
355
- try {
356
- const content = fs.readFileSync(goModPath, "utf-8");
357
- // Extract module name (first line: module example.com/module)
358
- const moduleMatch = content.match(/^module\s+(\S+)/m);
359
- if (moduleMatch)
360
- metadata.name = moduleMatch[1];
361
- // Extract go version
362
- const versionMatch = content.match(/^go\s+(\S+)/m);
363
- if (versionMatch)
364
- metadata.version = versionMatch[1];
365
- }
366
- catch {
367
- // Ignore parse errors
368
- }
369
- // Check for golangci-lint
370
- if (fs.existsSync(path.join(targetPath, ".golangci.yml")) ||
371
- fs.existsSync(path.join(targetPath, ".golangci.yaml"))) {
372
- metadata.hasLinting = true;
373
- metadata.linter = "golangci-lint";
374
- }
375
- return metadata;
376
- }
377
- /**
378
- * Detect PHP project from composer.json
379
- */
380
- function detectPhpProject(targetPath) {
381
- const composerPath = path.join(targetPath, "composer.json");
382
- if (!fs.existsSync(composerPath)) {
383
- return null;
384
- }
385
- let composerJson;
386
- try {
387
- composerJson = JSON.parse(fs.readFileSync(composerPath, "utf-8"));
388
- }
389
- catch {
390
- return null;
391
- }
392
- const metadata = {
393
- type: "php",
394
- packageManager: "composer",
395
- name: typeof composerJson.name === "string" ? composerJson.name : undefined,
396
- scripts: typeof composerJson.scripts === "object" && composerJson.scripts !== null
397
- ? composerJson.scripts
398
- : {},
399
- languages: ["php"],
400
- hasTests: false,
401
- hasLinting: false,
402
- hasFormatting: false,
403
- hasTypeScript: false,
404
- configFiles: ["composer.json"],
405
- };
406
- // Detect tests from scripts
407
- const scripts = Object.keys(metadata.scripts).join(" ").toLowerCase();
408
- if (scripts.includes("test") || scripts.includes("phpunit")) {
409
- metadata.hasTests = true;
410
- metadata.testFramework = "phpunit";
411
- }
412
- return metadata;
413
- }
414
- /**
415
- * Detect Ruby project from Gemfile
416
- */
417
- function detectRubyProject(targetPath) {
418
- const gemfilePath = path.join(targetPath, "Gemfile");
419
- const gemspecPath = fs.readdirSync(targetPath).find(f => f.endsWith(".gemspec"));
420
- if (!fs.existsSync(gemfilePath) && !gemspecPath) {
421
- return null;
422
- }
423
- const metadata = {
424
- type: "ruby",
425
- packageManager: "bundler",
426
- scripts: {},
427
- languages: ["ruby"],
428
- hasTests: false,
429
- hasLinting: false,
430
- hasFormatting: false,
431
- hasTypeScript: false,
432
- configFiles: [],
433
- };
434
- if (fs.existsSync(gemfilePath))
435
- metadata.configFiles.push("Gemfile");
436
- if (gemspecPath)
437
- metadata.configFiles.push(gemspecPath);
438
- // Check for Rakefile to get tasks
439
- const rakefilePath = path.join(targetPath, "Rakefile");
440
- if (fs.existsSync(rakefilePath)) {
441
- metadata.configFiles.push("Rakefile");
442
- }
443
- // Check for test framework
444
- if (fs.existsSync(path.join(targetPath, "spec"))) {
445
- metadata.hasTests = true;
446
- metadata.testFramework = "rspec";
447
- }
448
- else if (fs.existsSync(path.join(targetPath, "test"))) {
449
- metadata.hasTests = true;
450
- metadata.testFramework = "minitest";
451
- }
452
- // Check for rubocop
453
- if (fs.existsSync(path.join(targetPath, ".rubocop.yml"))) {
454
- metadata.hasLinting = true;
455
- metadata.linter = "rubocop";
456
- metadata.configFiles.push(".rubocop.yml");
457
- }
458
- return metadata;
459
- }
460
- function detectJavaProject(targetPath) {
461
- const hasPom = fs.existsSync(path.join(targetPath, "pom.xml"));
462
- const hasGradle = fs.existsSync(path.join(targetPath, "build.gradle")) ||
463
- fs.existsSync(path.join(targetPath, "build.gradle.kts"));
464
- if (!hasPom && !hasGradle)
465
- return null;
466
- return {
467
- type: "java",
468
- packageManager: hasPom ? "maven" : "gradle",
469
- scripts: {},
470
- languages: ["java"],
471
- hasTests: true,
472
- hasLinting: false,
473
- hasFormatting: false,
474
- hasTypeScript: false,
475
- configFiles: hasPom ? ["pom.xml"] : ["build.gradle"],
476
- };
477
- }
478
- function detectKotlinProject(targetPath) {
479
- const hasGradleKts = fs.existsSync(path.join(targetPath, "build.gradle.kts"));
480
- const hasKotlinSrc = fs.existsSync(path.join(targetPath, "src", "main", "kotlin"));
481
- if (!hasGradleKts && !hasKotlinSrc)
482
- return null;
483
- return {
484
- type: "kotlin",
485
- packageManager: "gradle",
486
- scripts: {},
487
- languages: ["kotlin"],
488
- hasTests: true,
489
- hasLinting: false,
490
- hasFormatting: false,
491
- hasTypeScript: false,
492
- configFiles: hasGradleKts ? ["build.gradle.kts"] : [],
493
- };
494
- }
495
- function detectCsharpProject(targetPath) {
496
- const entries = fs.readdirSync(targetPath);
497
- const hasSln = entries.some(e => /\.(sln|slnx)$/i.test(e));
498
- const hasCsproj = entries.some(e => /\.csproj$/i.test(e));
499
- if (!hasSln && !hasCsproj)
500
- return null;
501
- const configFile = entries.find(e => /\.(sln|slnx|csproj)$/i.test(e)) ?? "";
502
- return {
503
- type: "csharp",
504
- packageManager: "dotnet",
505
- scripts: {},
506
- languages: ["csharp"],
507
- hasTests: true,
508
- hasLinting: false,
509
- hasFormatting: false,
510
- hasTypeScript: false,
511
- configFiles: [configFile],
512
- };
513
- }
514
- function detectDartProject(targetPath) {
515
- if (!fs.existsSync(path.join(targetPath, "pubspec.yaml")))
516
- return null;
517
- return {
518
- type: "dart",
519
- packageManager: "pub",
520
- scripts: {},
521
- languages: ["dart"],
522
- hasTests: true,
523
- hasLinting: false,
524
- hasFormatting: false,
525
- hasTypeScript: false,
526
- configFiles: ["pubspec.yaml"],
527
- };
528
- }
529
- function detectGleamProject(targetPath) {
530
- if (!fs.existsSync(path.join(targetPath, "gleam.toml")))
531
- return null;
532
- return {
533
- type: "gleam",
534
- packageManager: "gleam",
535
- scripts: {},
536
- languages: ["gleam"],
537
- hasTests: true,
538
- hasLinting: false,
539
- hasFormatting: false,
540
- hasTypeScript: false,
541
- configFiles: ["gleam.toml"],
542
- };
543
- }
544
- function detectZigProject(targetPath) {
545
- if (!fs.existsSync(path.join(targetPath, "build.zig")))
546
- return null;
547
- return {
548
- type: "zig",
549
- packageManager: "zig",
550
- scripts: {},
551
- languages: ["zig"],
552
- hasTests: true,
553
- hasLinting: false,
554
- hasFormatting: false,
555
- hasTypeScript: false,
556
- configFiles: ["build.zig"],
557
- };
558
- }
559
- function detectElixirProject(targetPath) {
560
- if (!fs.existsSync(path.join(targetPath, "mix.exs")))
561
- return null;
562
- return {
563
- type: "elixir",
564
- packageManager: "mix",
565
- scripts: {},
566
- languages: ["elixir"],
567
- hasTests: true,
568
- hasLinting: false,
569
- hasFormatting: false,
570
- hasTypeScript: false,
571
- configFiles: ["mix.exs"],
572
- };
573
- }
574
- function detectCppProject(targetPath) {
575
- const hasCmake = fs.existsSync(path.join(targetPath, "CMakeLists.txt"));
576
- const hasMakefile = fs.existsSync(path.join(targetPath, "Makefile"));
577
- // Also detect by source files if no build system marker
578
- const hasCppFiles = fs.existsSync(targetPath) &&
579
- fs.readdirSync(targetPath).some(f => /\.(cpp|cxx|cc|c\+\+)$/i.test(f));
580
- if (!hasCmake && !hasMakefile && !hasCppFiles)
581
- return null;
582
- const configFiles = [];
583
- if (hasCmake)
584
- configFiles.push("CMakeLists.txt");
585
- if (hasMakefile)
586
- configFiles.push("Makefile");
587
- return {
588
- type: "cpp",
589
- scripts: {},
590
- languages: ["cpp"],
591
- hasTests: false,
592
- hasLinting: false,
593
- hasFormatting: false,
594
- hasTypeScript: false,
595
- configFiles,
596
- };
597
- }
598
- // --- Formatting Utilities ---
599
- /**
600
- * Format project metadata for display in reports
601
- */
602
- export function formatProjectMetadata(metadata) {
603
- const lines = [];
604
- // Header
605
- const name = metadata.name ? `**${metadata.name}**` : "Project";
606
- const type = metadata.type !== "unknown" ? `(${capitalize(metadata.type)})` : "";
607
- lines.push(`๐Ÿ“Š ${name} ${type}`.trim());
608
- // Package manager
609
- if (metadata.packageManager) {
610
- lines.push(`๐Ÿ“ฆ Package Manager: ${capitalize(metadata.packageManager)}`);
611
- }
612
- // Languages
613
- if (metadata.languages.length > 0) {
614
- lines.push(`๐Ÿ“ Languages: ${metadata.languages.map(capitalize).join(", ")}`);
615
- }
616
- // Tools
617
- const tools = [];
618
- if (metadata.hasTests) {
619
- tools.push(metadata.testFramework ? `๐Ÿงช ${metadata.testFramework}` : "๐Ÿงช tests");
620
- }
621
- if (metadata.hasLinting) {
622
- tools.push(metadata.linter ? `๐Ÿ” ${metadata.linter}` : "๐Ÿ” linting");
623
- }
624
- if (metadata.hasFormatting) {
625
- tools.push(metadata.formatter ? `โœจ ${metadata.formatter}` : "โœจ formatting");
626
- }
627
- if (tools.length > 0) {
628
- lines.push(tools.join(" | "));
629
- }
630
- // Config files (limited)
631
- if (metadata.configFiles.length > 0) {
632
- const limited = metadata.configFiles.slice(0, 5);
633
- const more = metadata.configFiles.length > 5 ? ` (+${metadata.configFiles.length - 5} more)` : "";
634
- lines.push(`โš™๏ธ Config: ${limited.join(", ")}${more}`);
635
- }
636
- return lines.join("\n");
637
- }
638
- /**
639
- * Get available commands for a project (build, test, lint, etc.)
640
- */
641
- export function getAvailableCommands(metadata) {
642
- const commands = [];
643
- // Node.js projects - use npm scripts
644
- if (metadata.type === "node" && Object.keys(metadata.scripts).length > 0) {
645
- const scriptPriority = ["test", "build", "lint", "format", "dev", "start", "typecheck"];
646
- for (const priority of scriptPriority) {
647
- const matching = Object.entries(metadata.scripts).find(([name]) => name.toLowerCase().includes(priority));
648
- if (matching) {
649
- const pm = (metadata.packageManager ?? "npm");
650
- commands.push({
651
- action: priority,
652
- command: formatRunScript(pm, matching[0]),
653
- });
654
- }
655
- }
656
- }
657
- // Python projects
658
- if (metadata.type === "python") {
659
- if (metadata.hasTests) {
660
- const testCmd = metadata.packageManager === "poetry" ? "poetry run pytest" :
661
- metadata.packageManager === "uv" ? "uv run pytest" :
662
- "pytest";
663
- commands.push({ action: "test", command: testCmd });
664
- }
665
- if (metadata.linter?.includes("ruff")) {
666
- commands.push({ action: "lint", command: "ruff check ." });
667
- commands.push({ action: "format", command: "ruff format ." });
668
- }
669
- }
670
- // Rust projects
671
- if (metadata.type === "rust") {
672
- commands.push({ action: "build", command: "cargo build" });
673
- commands.push({ action: "test", command: "cargo test" });
674
- if (metadata.hasLinting) {
675
- commands.push({ action: "lint", command: "cargo clippy" });
676
- }
677
- }
678
- // Go projects
679
- if (metadata.type === "go") {
680
- commands.push({ action: "build", command: "go build" });
681
- commands.push({ action: "test", command: "go test ./..." });
682
- if (metadata.hasLinting) {
683
- commands.push({ action: "lint", command: "golangci-lint run" });
684
- }
685
- }
686
- return commands;
687
- }
688
- function capitalize(str) {
689
- return str.charAt(0).toUpperCase() + str.slice(1);
690
- }