@herbertgao/pi-extensions 2026.9.19 → 2026.10.0

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 (444) hide show
  1. package/README.md +14 -16
  2. package/THIRD_PARTY_NOTICES.md +29 -3
  3. package/node_modules/@herbertgao/pi-bark/README.md +39 -3
  4. package/node_modules/@herbertgao/pi-bark/package.json +1 -1
  5. package/node_modules/@herbertgao/pi-bark/src/index.ts +275 -15
  6. package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +85 -68
  7. package/node_modules/@herbertgao/pi-cc-extensions/README.md +79 -62
  8. package/node_modules/@herbertgao/pi-cc-extensions/assets/readme/preview.webp +0 -0
  9. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +116 -34
  10. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +370 -118
  11. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/agent-summary/core.ts +6 -36
  12. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/agent-summary/index.ts +2 -2
  13. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +31 -33
  14. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +330 -360
  15. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/reference/index.ts +56 -108
  16. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/reference/session.ts +97 -15
  17. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/reference/subagent.ts +80 -45
  18. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/flush-docked-bash.ts +36 -0
  19. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/footer-layout.ts +229 -0
  20. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/footer.ts +521 -0
  21. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/mcp-chip.ts +136 -0
  22. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/startup-header.ts +92 -61
  23. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/working-message.ts +58 -38
  24. package/node_modules/@herbertgao/pi-cc-extensions/extensions/index.ts +19 -3
  25. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +1127 -231
  26. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +267 -262
  27. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/index.ts +38 -48
  28. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/markdown-enhance.ts +8 -2
  29. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/hover.ts +2 -7
  30. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/interaction.ts +287 -114
  31. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/layout.ts +15 -6
  32. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/packets.ts +18 -72
  33. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/scroll.ts +61 -26
  34. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/codemode.ts +303 -0
  35. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/ansi-utils.ts +25 -57
  36. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-component.ts +125 -0
  37. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-edit-render.ts +227 -0
  38. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-header.ts +136 -0
  39. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-highlight.ts +151 -0
  40. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-inline.ts +324 -0
  41. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-layout.ts +762 -0
  42. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-limits.ts +152 -0
  43. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-palette.ts +410 -0
  44. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-parse.ts +535 -0
  45. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-presentation.ts +4 -4
  46. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-renderer.ts +21 -3219
  47. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-text.ts +44 -0
  48. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-write-render.ts +568 -0
  49. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/index.ts +103 -48
  50. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/line-width-safety.ts +8 -7
  51. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/write-execution.ts +2 -1
  52. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +171 -196
  53. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/mcp-title.ts +39 -0
  54. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{message-display.ts → tool/message-display.ts} +27 -93
  55. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/names.ts +429 -0
  56. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/result.ts +259 -164
  57. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{show-more-hint.ts → tool/show-more-hint.ts} +10 -0
  58. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/transcript-refresh.ts +8 -26
  59. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/ansi-color.ts +44 -0
  60. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/ansi-text.ts +77 -0
  61. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/component-tree.ts +34 -0
  62. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/format.ts +28 -0
  63. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/fullscreen-detect.ts +51 -0
  64. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/patch-keys.ts +124 -0
  65. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/sgr-mouse.ts +70 -0
  66. package/node_modules/@herbertgao/pi-cc-extensions/package.json +10 -8
  67. package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +6 -0
  68. package/node_modules/@herbertgao/pi-subagents/package.json +1 -1
  69. package/node_modules/@herbertgao/pi-subagents/src/mention-clone.ts +3 -2
  70. package/node_modules/@herbertgao/sol-pi/CONTRIBUTING.md +22 -0
  71. package/node_modules/@herbertgao/sol-pi/README.md +36 -17
  72. package/node_modules/@herbertgao/sol-pi/THIRD_PARTY_NOTICES.md +10 -6
  73. package/node_modules/@herbertgao/sol-pi/agents-install.md +15 -12
  74. package/node_modules/@herbertgao/sol-pi/docs/compatibility.md +24 -8
  75. package/node_modules/@herbertgao/sol-pi/docs/configuration.md +2 -2
  76. package/node_modules/@herbertgao/sol-pi/docs/star-history.md +18 -0
  77. package/node_modules/@herbertgao/sol-pi/package.json +4 -2
  78. package/node_modules/@herbertgao/sol-pi/scripts/check-sol-pi-config.mjs +1 -1
  79. package/node_modules/@herbertgao/sol-pi/src/sol-pi/config.ts +1 -1
  80. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/file-queue.ts +23 -4
  81. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/index.ts +32 -1
  82. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/action-fusion/then-run.ts +3 -2
  83. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/observation-pack/observation.ts +1 -1
  84. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/economics.ts +27 -7
  85. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/extension.ts +137 -41
  86. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/index.ts +1 -0
  87. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/plan.ts +2 -1
  88. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/projection.ts +58 -0
  89. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/state.ts +28 -6
  90. package/node_modules/@herbertgao/sol-pi/src/sol-pi/extensions/online-context-compact/tools.ts +2 -1
  91. package/node_modules/@herbertgao/sol-pi/src/sol-pi/runtime-paths.ts +15 -2
  92. package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +2 -2
  93. package/node_modules/@pi-plugins/fast-mode/README.md +7 -1
  94. package/node_modules/@pi-plugins/fast-mode/dist/index.d.mts.map +1 -1
  95. package/node_modules/@pi-plugins/fast-mode/dist/index.mjs +7 -1
  96. package/node_modules/@pi-plugins/fast-mode/dist/index.mjs.map +1 -1
  97. package/node_modules/@pi-plugins/fast-mode/package.json +5 -5
  98. package/node_modules/pi-antigravity/README.md +3 -0
  99. package/node_modules/pi-antigravity/package.json +8 -8
  100. package/node_modules/pi-antigravity/src/auth/oauth.ts +6 -3
  101. package/node_modules/pi-antigravity/src/index.ts +114 -110
  102. package/node_modules/pi-antigravity/src/stream/stream.ts +1 -1
  103. package/node_modules/pi-antigravity/src/utils/util.ts +18 -1
  104. package/node_modules/pi-multi-account/CHANGELOG.md +20 -0
  105. package/node_modules/pi-multi-account/README.md +46 -8
  106. package/node_modules/pi-multi-account/config-file-transaction.ts +42 -0
  107. package/node_modules/pi-multi-account/index.ts +255 -269
  108. package/node_modules/pi-multi-account/model-pins.ts +36 -0
  109. package/node_modules/pi-multi-account/package.json +9 -7
  110. package/node_modules/pi-multi-account/slot-proxy-auth.ts +12 -2
  111. package/node_modules/pi-multi-account/slot-proxy.ts +27 -5
  112. package/node_modules/pi-web-access/CHANGELOG.md +17 -0
  113. package/node_modules/pi-web-access/README.md +6 -3
  114. package/node_modules/pi-web-access/brave-rate-limit.ts +170 -0
  115. package/node_modules/pi-web-access/brave.ts +28 -11
  116. package/node_modules/pi-web-access/dist/index.js +202 -33
  117. package/node_modules/pi-web-access/gemini-search.ts +2 -5
  118. package/node_modules/pi-web-access/index.ts +13 -7
  119. package/node_modules/pi-web-access/openai-search.ts +24 -10
  120. package/node_modules/pi-web-access/package.json +1 -1
  121. package/node_modules/pi-web-access/summary-review.ts +8 -2
  122. package/node_modules/{@herbertgao/resume-from → resume-from}/README.md +16 -12
  123. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/adapter.d.ts +0 -5
  124. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/adapter.js +2 -3
  125. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/contract.d.ts +2 -2
  126. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/reader.d.ts +3 -0
  127. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/reader.js +27 -15
  128. package/node_modules/{@herbertgao/resume-from/dist/adapters/codex → resume-from/dist/adapters/claude-code}/redaction.js +16 -3
  129. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/writer.d.ts +2 -4
  130. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/writer.js +1 -1
  131. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/contract.d.ts +2 -4
  132. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/index.js +1 -2
  133. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/read.d.ts +16 -0
  134. package/node_modules/resume-from/dist/adapters/codex/read.js +723 -0
  135. package/node_modules/{@herbertgao/resume-from/dist/adapters/pi → resume-from/dist/adapters/codex}/redaction.js +16 -3
  136. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/rollout.d.ts +44 -4
  137. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/rollout.js +88 -4
  138. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/write.d.ts +2 -2
  139. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/write.js +2 -2
  140. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/contract.d.ts +5 -1
  141. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/adapter.js +10 -6
  142. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/contract.d.ts +2 -2
  143. package/node_modules/{@herbertgao/resume-from/dist/adapters/claude-code → resume-from/dist/adapters/pi}/redaction.js +16 -3
  144. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/serialize.d.ts +2 -4
  145. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/serialize.js +2 -2
  146. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/render.d.ts +1 -1
  147. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/render.js +4 -4
  148. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/runner.js +2 -2
  149. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/contract.d.ts +2 -2
  150. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/command.js +31 -8
  151. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/wiring.d.ts +1 -1
  152. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/wiring.js +1 -2
  153. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/confirmation.d.ts +4 -1
  154. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/confirmation.js +2 -2
  155. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/contract.d.ts +8 -6
  156. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/contract.d.ts +10 -5
  157. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/finder.d.ts +2 -1
  158. package/node_modules/resume-from/dist/import/discovery/finder.js +269 -0
  159. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/contract.d.ts +3 -3
  160. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/lander.js +3 -3
  161. package/node_modules/resume-from/dist/import/pipeline.d.ts +28 -0
  162. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/pipeline.js +31 -11
  163. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/builder.d.ts +2 -2
  164. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/builder.js +9 -5
  165. package/node_modules/resume-from/dist/import/preview/warnings.d.ts +14 -0
  166. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/warnings.js +26 -20
  167. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/wiring.js +12 -2
  168. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/contract.d.ts +9 -3
  169. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/git.d.ts +4 -4
  170. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/git.js +7 -4
  171. package/node_modules/resume-from/dist/platform/repo/reader.d.ts +3 -0
  172. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/reader.js +60 -20
  173. package/node_modules/{@herbertgao/resume-from → resume-from}/dist/session/contract.d.ts +8 -1
  174. package/node_modules/{@herbertgao/resume-from → resume-from}/package.json +19 -32
  175. package/node_modules/{@herbertgao/resume-from → resume-from}/shims/pi/extensions/resume-from.js +2 -2
  176. package/package.json +18 -22
  177. package/node_modules/@herbertgao/pi-cc-extensions/assets/readme/hero.en.svg +0 -101
  178. package/node_modules/@herbertgao/pi-cc-extensions/assets/readme/hero.svg +0 -101
  179. package/node_modules/@herbertgao/pi-cc-extensions/assets/readme/welcome.webp +0 -0
  180. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/render-utils.ts +0 -5
  181. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/types.ts +0 -30
  182. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/write-display-utils.ts +0 -12
  183. package/node_modules/@herbertgao/resume-from/dist/adapters/codex/read.js +0 -270
  184. package/node_modules/@herbertgao/resume-from/dist/import/discovery/finder.js +0 -129
  185. package/node_modules/@herbertgao/resume-from/dist/import/pipeline.d.ts +0 -17
  186. package/node_modules/@herbertgao/resume-from/dist/import/preview/warnings.d.ts +0 -11
  187. package/node_modules/@herbertgao/resume-from/dist/platform/repo/reader.d.ts +0 -8
  188. package/node_modules/pi-footer/CHANGELOG.md +0 -145
  189. package/node_modules/pi-footer/LICENSE +0 -21
  190. package/node_modules/pi-footer/README.md +0 -354
  191. package/node_modules/pi-footer/package.json +0 -68
  192. package/node_modules/pi-footer/src/cache.ts +0 -106
  193. package/node_modules/pi-footer/src/colors.ts +0 -237
  194. package/node_modules/pi-footer/src/config.ts +0 -202
  195. package/node_modules/pi-footer/src/event-widgets.ts +0 -41
  196. package/node_modules/pi-footer/src/extension-statuses.ts +0 -102
  197. package/node_modules/pi-footer/src/git.ts +0 -135
  198. package/node_modules/pi-footer/src/index.ts +0 -268
  199. package/node_modules/pi-footer/src/metrics.ts +0 -141
  200. package/node_modules/pi-footer/src/presets.ts +0 -383
  201. package/node_modules/pi-footer/src/render.ts +0 -114
  202. package/node_modules/pi-footer/src/separators.ts +0 -52
  203. package/node_modules/pi-footer/src/types.ts +0 -122
  204. package/node_modules/pi-footer/src/ui/color-level-confirm.ts +0 -22
  205. package/node_modules/pi-footer/src/ui/color-options.ts +0 -195
  206. package/node_modules/pi-footer/src/ui/config-lifecycle.ts +0 -61
  207. package/node_modules/pi-footer/src/ui/edit-colors.ts +0 -13
  208. package/node_modules/pi-footer/src/ui/events.ts +0 -35
  209. package/node_modules/pi-footer/src/ui/extension-status-picker.ts +0 -60
  210. package/node_modules/pi-footer/src/ui/extension-statuses.ts +0 -73
  211. package/node_modules/pi-footer/src/ui/fields.ts +0 -252
  212. package/node_modules/pi-footer/src/ui/global-menu.ts +0 -126
  213. package/node_modules/pi-footer/src/ui/helpers.ts +0 -44
  214. package/node_modules/pi-footer/src/ui/layout.ts +0 -17
  215. package/node_modules/pi-footer/src/ui/line-list.ts +0 -19
  216. package/node_modules/pi-footer/src/ui/model.ts +0 -64
  217. package/node_modules/pi-footer/src/ui/navigation.ts +0 -29
  218. package/node_modules/pi-footer/src/ui/option-edit.ts +0 -93
  219. package/node_modules/pi-footer/src/ui/overlay-render.ts +0 -103
  220. package/node_modules/pi-footer/src/ui/screen-context.ts +0 -18
  221. package/node_modules/pi-footer/src/ui/screen-controller.ts +0 -27
  222. package/node_modules/pi-footer/src/ui/screen-render.ts +0 -32
  223. package/node_modules/pi-footer/src/ui/screen-state.ts +0 -20
  224. package/node_modules/pi-footer/src/ui/screen.ts +0 -243
  225. package/node_modules/pi-footer/src/ui/screens/add-widget.ts +0 -92
  226. package/node_modules/pi-footer/src/ui/screens/confirm-exit.ts +0 -52
  227. package/node_modules/pi-footer/src/ui/screens/controller.ts +0 -12
  228. package/node_modules/pi-footer/src/ui/screens/edit-colors.ts +0 -68
  229. package/node_modules/pi-footer/src/ui/screens/edit-widget.ts +0 -115
  230. package/node_modules/pi-footer/src/ui/screens/extension-status-row.ts +0 -61
  231. package/node_modules/pi-footer/src/ui/screens/global.ts +0 -75
  232. package/node_modules/pi-footer/src/ui/screens/line-list.ts +0 -108
  233. package/node_modules/pi-footer/src/ui/screens/main.ts +0 -99
  234. package/node_modules/pi-footer/src/ui/screens/terminal.ts +0 -121
  235. package/node_modules/pi-footer/src/ui/screens/widget-list.ts +0 -154
  236. package/node_modules/pi-footer/src/ui/terminal-menu.ts +0 -32
  237. package/node_modules/pi-footer/src/ui/theme.ts +0 -48
  238. package/node_modules/pi-footer/src/ui/title-bar.ts +0 -100
  239. package/node_modules/pi-footer/src/ui/widget-actions.ts +0 -76
  240. package/node_modules/pi-footer/src/ui.ts +0 -66
  241. package/node_modules/pi-footer/src/widgets/context.ts +0 -28
  242. package/node_modules/pi-footer/src/widgets/core/active-tools.ts +0 -17
  243. package/node_modules/pi-footer/src/widgets/core/context-window.ts +0 -24
  244. package/node_modules/pi-footer/src/widgets/core/cwd-basename.ts +0 -19
  245. package/node_modules/pi-footer/src/widgets/core/cwd.ts +0 -108
  246. package/node_modules/pi-footer/src/widgets/core/event.ts +0 -34
  247. package/node_modules/pi-footer/src/widgets/core/external-status.ts +0 -102
  248. package/node_modules/pi-footer/src/widgets/core/model-provider.ts +0 -20
  249. package/node_modules/pi-footer/src/widgets/core/model.ts +0 -35
  250. package/node_modules/pi-footer/src/widgets/core/provider.ts +0 -17
  251. package/node_modules/pi-footer/src/widgets/core/session-name.ts +0 -17
  252. package/node_modules/pi-footer/src/widgets/core/text-verbosity.ts +0 -17
  253. package/node_modules/pi-footer/src/widgets/core/thinking-level.ts +0 -17
  254. package/node_modules/pi-footer/src/widgets/git/ahead-behind.ts +0 -17
  255. package/node_modules/pi-footer/src/widgets/git/branch.ts +0 -81
  256. package/node_modules/pi-footer/src/widgets/git/clean.ts +0 -19
  257. package/node_modules/pi-footer/src/widgets/git/deletions.ts +0 -17
  258. package/node_modules/pi-footer/src/widgets/git/diff.ts +0 -38
  259. package/node_modules/pi-footer/src/widgets/git/insertions.ts +0 -17
  260. package/node_modules/pi-footer/src/widgets/git/remote.ts +0 -17
  261. package/node_modules/pi-footer/src/widgets/git/root.ts +0 -17
  262. package/node_modules/pi-footer/src/widgets/git/sha.ts +0 -17
  263. package/node_modules/pi-footer/src/widgets/git/staged.ts +0 -17
  264. package/node_modules/pi-footer/src/widgets/git/status.ts +0 -19
  265. package/node_modules/pi-footer/src/widgets/git/unstaged.ts +0 -17
  266. package/node_modules/pi-footer/src/widgets/git/untracked.ts +0 -17
  267. package/node_modules/pi-footer/src/widgets/instance.ts +0 -118
  268. package/node_modules/pi-footer/src/widgets/layout/custom-text.ts +0 -18
  269. package/node_modules/pi-footer/src/widgets/layout/flex-separator.ts +0 -32
  270. package/node_modules/pi-footer/src/widgets/layout/separator.ts +0 -57
  271. package/node_modules/pi-footer/src/widgets/layout/spacer.ts +0 -31
  272. package/node_modules/pi-footer/src/widgets/options.ts +0 -122
  273. package/node_modules/pi-footer/src/widgets/project/runtime.ts +0 -361
  274. package/node_modules/pi-footer/src/widgets/registry.ts +0 -223
  275. package/node_modules/pi-footer/src/widgets/session/assistant-messages.ts +0 -17
  276. package/node_modules/pi-footer/src/widgets/session/compactions.ts +0 -17
  277. package/node_modules/pi-footer/src/widgets/session/elapsed.ts +0 -18
  278. package/node_modules/pi-footer/src/widgets/session/last-activity.ts +0 -18
  279. package/node_modules/pi-footer/src/widgets/session/messages.ts +0 -19
  280. package/node_modules/pi-footer/src/widgets/session/session-id.ts +0 -17
  281. package/node_modules/pi-footer/src/widgets/session/session-start.ts +0 -18
  282. package/node_modules/pi-footer/src/widgets/session/tool-results.ts +0 -17
  283. package/node_modules/pi-footer/src/widgets/session/total-messages.ts +0 -19
  284. package/node_modules/pi-footer/src/widgets/session/total-time.ts +0 -18
  285. package/node_modules/pi-footer/src/widgets/session/user-messages.ts +0 -17
  286. package/node_modules/pi-footer/src/widgets/store.ts +0 -26
  287. package/node_modules/pi-footer/src/widgets/tokens/cache-hit-rate.ts +0 -55
  288. package/node_modules/pi-footer/src/widgets/tokens/cache-read.ts +0 -18
  289. package/node_modules/pi-footer/src/widgets/tokens/cache-write.ts +0 -18
  290. package/node_modules/pi-footer/src/widgets/tokens/context-bar.ts +0 -108
  291. package/node_modules/pi-footer/src/widgets/tokens/context-length.ts +0 -26
  292. package/node_modules/pi-footer/src/widgets/tokens/context-remaining.ts +0 -29
  293. package/node_modules/pi-footer/src/widgets/tokens/context.ts +0 -29
  294. package/node_modules/pi-footer/src/widgets/tokens/cost.ts +0 -51
  295. package/node_modules/pi-footer/src/widgets/tokens/input-speed.ts +0 -25
  296. package/node_modules/pi-footer/src/widgets/tokens/input-tokens.ts +0 -18
  297. package/node_modules/pi-footer/src/widgets/tokens/output-speed.ts +0 -25
  298. package/node_modules/pi-footer/src/widgets/tokens/output-tokens.ts +0 -18
  299. package/node_modules/pi-footer/src/widgets/tokens/tokens.ts +0 -20
  300. package/node_modules/pi-footer/src/widgets/tokens/total-speed.ts +0 -25
  301. package/node_modules/pi-footer/src/widgets/tokens/total-tokens.ts +0 -18
  302. package/node_modules/pi-footer/src/widgets/types.ts +0 -181
  303. package/node_modules/pi-footer/src/widgets/utils/colors.ts +0 -11
  304. package/node_modules/pi-footer/src/widgets/utils/context.ts +0 -112
  305. package/node_modules/pi-footer/src/widgets/utils/session.ts +0 -19
  306. package/node_modules/pi-footer/src/widgets/utils/token-format.ts +0 -78
  307. /package/node_modules/{@herbertgao/resume-from → resume-from}/LICENSE +0 -0
  308. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/contract.js +0 -0
  309. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/entries.d.ts +0 -0
  310. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/entries.js +0 -0
  311. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/index.d.ts +0 -0
  312. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/index.js +0 -0
  313. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/layout.d.ts +0 -0
  314. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/layout.js +0 -0
  315. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/readback.d.ts +0 -0
  316. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/readback.js +0 -0
  317. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/redaction.d.ts +0 -0
  318. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/validation.d.ts +0 -0
  319. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/claude-code/validation.js +0 -0
  320. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/contract.js +0 -0
  321. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/index.d.ts +0 -0
  322. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/readback.d.ts +0 -0
  323. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/readback.js +0 -0
  324. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/redaction.d.ts +0 -0
  325. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/validation.d.ts +0 -0
  326. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/codex/validation.js +0 -0
  327. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/contract.js +0 -0
  328. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/adapter.d.ts +0 -0
  329. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/contract.js +0 -0
  330. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/format.d.ts +0 -0
  331. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/format.js +0 -0
  332. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/index.d.ts +0 -0
  333. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/index.js +0 -0
  334. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/parse.d.ts +0 -0
  335. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/parse.js +0 -0
  336. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/redaction.d.ts +0 -0
  337. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/validate.d.ts +0 -0
  338. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/adapters/pi/validate.js +0 -0
  339. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/bin.d.ts +0 -0
  340. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/bin.js +0 -0
  341. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/contract.d.ts +0 -0
  342. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/contract.js +0 -0
  343. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/agents.d.ts +0 -0
  344. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/agents.js +0 -0
  345. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/args.d.ts +0 -0
  346. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/args.js +0 -0
  347. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/contract.d.ts +0 -0
  348. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/contract.js +0 -0
  349. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/index.d.ts +0 -0
  350. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/index.js +0 -0
  351. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/presentation.d.ts +0 -0
  352. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/presentation.js +0 -0
  353. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/cli/runner.d.ts +0 -0
  354. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/contract.js +0 -0
  355. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/entry.d.ts +0 -0
  356. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/entry.js +0 -0
  357. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/index.d.ts +0 -0
  358. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/index.js +0 -0
  359. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/command.d.ts +0 -0
  360. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/contract.d.ts +0 -0
  361. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/contract.js +0 -0
  362. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/index.d.ts +0 -0
  363. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/index.js +0 -0
  364. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/picker.d.ts +0 -0
  365. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/picker.js +0 -0
  366. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/presentation.d.ts +0 -0
  367. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/presentation.js +0 -0
  368. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/register.d.ts +0 -0
  369. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/register.js +0 -0
  370. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/ui.d.ts +0 -0
  371. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/pi-extension/ui.js +0 -0
  372. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/profile.d.ts +0 -0
  373. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/profile.js +0 -0
  374. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/registry.d.ts +0 -0
  375. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/host/registry.js +0 -0
  376. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/contract.js +0 -0
  377. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/contract.js +0 -0
  378. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/errors.d.ts +0 -0
  379. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/errors.js +0 -0
  380. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/homes.d.ts +0 -0
  381. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/homes.js +0 -0
  382. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/index.d.ts +0 -0
  383. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/index.js +0 -0
  384. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/ordering.d.ts +0 -0
  385. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/discovery/ordering.js +0 -0
  386. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/errors.d.ts +0 -0
  387. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/errors.js +0 -0
  388. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/index.d.ts +0 -0
  389. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/index.js +0 -0
  390. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/contract.js +0 -0
  391. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/errors.d.ts +0 -0
  392. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/errors.js +0 -0
  393. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/handover.d.ts +0 -0
  394. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/handover.js +0 -0
  395. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/index.d.ts +0 -0
  396. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/index.js +0 -0
  397. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/lander.d.ts +0 -0
  398. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/marker.d.ts +0 -0
  399. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/landing/marker.js +0 -0
  400. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/contract.d.ts +0 -0
  401. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/contract.js +0 -0
  402. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/format.d.ts +0 -0
  403. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/format.js +0 -0
  404. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/index.d.ts +0 -0
  405. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/preview/index.js +0 -0
  406. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/contract.d.ts +0 -0
  407. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/contract.js +0 -0
  408. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/index.d.ts +0 -0
  409. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/index.js +0 -0
  410. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/rules.d.ts +0 -0
  411. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/transfer/rules.js +0 -0
  412. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/import/wiring.d.ts +0 -0
  413. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/index.d.ts +0 -0
  414. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/index.js +0 -0
  415. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/contract.d.ts +0 -0
  416. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/contract.js +0 -0
  417. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/defaults.d.ts +0 -0
  418. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/defaults.js +0 -0
  419. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/errors.d.ts +0 -0
  420. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/errors.js +0 -0
  421. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/index.d.ts +0 -0
  422. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/index.js +0 -0
  423. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/loader.d.ts +0 -0
  424. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/loader.js +0 -0
  425. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/paths.d.ts +0 -0
  426. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/paths.js +0 -0
  427. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/validate.d.ts +0 -0
  428. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/config/validate.js +0 -0
  429. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/contract.js +0 -0
  430. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/index.d.ts +0 -0
  431. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/repo/index.js +0 -0
  432. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/contract.d.ts +0 -0
  433. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/contract.js +0 -0
  434. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/file-committer.d.ts +0 -0
  435. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/file-committer.js +0 -0
  436. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/index.d.ts +0 -0
  437. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/store/index.js +0 -0
  438. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/contract.d.ts +0 -0
  439. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/contract.js +0 -0
  440. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/estimator.d.ts +0 -0
  441. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/estimator.js +0 -0
  442. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/index.d.ts +0 -0
  443. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/platform/tokens/index.js +0 -0
  444. /package/node_modules/{@herbertgao/resume-from → resume-from}/dist/session/contract.js +0 -0
@@ -1,106 +0,0 @@
1
- export const CACHE_NAMESPACES = { runtime: "runtime", git: "git" } as const;
2
- type CacheNamespace = (typeof CACHE_NAMESPACES)[keyof typeof CACHE_NAMESPACES];
3
-
4
- interface CacheEntry<V> {
5
- value: V | null;
6
- updatedAt: number | null;
7
- pending: Promise<void> | null;
8
- listeners: Set<() => void>;
9
- }
10
-
11
- export class AsyncCache {
12
- private readonly entries = new Map<string, CacheEntry<unknown>>();
13
- private readonly maxEntries: number;
14
- private readonly now: () => number;
15
-
16
- constructor(maxEntries = 200, now: () => number = () => Date.now()) {
17
- this.maxEntries = maxEntries;
18
- this.now = now;
19
- }
20
-
21
- get<K, V, F>(
22
- ns: CacheNamespace,
23
- key: K,
24
- ttlMs: number,
25
- filter: F,
26
- fetcher: (filter: F) => Promise<V | null>,
27
- onRefresh?: () => void,
28
- ): V | null {
29
- const cacheKey = this.cacheKey(ns, key);
30
- const entry = this.entryFor<V>(cacheKey);
31
- if (this.isFresh(entry, ttlMs)) return entry.value;
32
-
33
- this.addListener(entry, onRefresh);
34
- if (!entry.pending) entry.pending = this.refresh(entry, filter, fetcher);
35
-
36
- return entry.value;
37
- }
38
-
39
- clear(): void {
40
- this.entries.clear();
41
- }
42
-
43
- private entryFor<V>(cacheKey: string): CacheEntry<V> {
44
- const cached = this.entries.get(cacheKey);
45
- if (cached) return cached as CacheEntry<V>;
46
-
47
- const entry: CacheEntry<V> = {
48
- value: null,
49
- updatedAt: null,
50
- pending: null,
51
- listeners: new Set(),
52
- };
53
- this.entries.set(cacheKey, entry as CacheEntry<unknown>);
54
- this.evictOldestEntry();
55
- return entry;
56
- }
57
-
58
- private isFresh<V>(entry: CacheEntry<V>, ttlMs: number): boolean {
59
- return entry.updatedAt !== null && this.now() - entry.updatedAt < ttlMs;
60
- }
61
-
62
- private addListener<V>(entry: CacheEntry<V>, listener: (() => void) | undefined): void {
63
- if (listener) entry.listeners.add(listener);
64
- }
65
-
66
- private async refresh<V, F>(
67
- entry: CacheEntry<V>,
68
- filter: F,
69
- fetcher: (filter: F) => Promise<V | null>,
70
- ): Promise<void> {
71
- try {
72
- entry.value = await fetcher(filter);
73
- } catch {
74
- entry.value = null;
75
- } finally {
76
- entry.updatedAt = this.now();
77
- entry.pending = null;
78
- this.notify(entry);
79
- }
80
- }
81
-
82
- private notify<V>(entry: CacheEntry<V>): void {
83
- const listeners = [...entry.listeners];
84
- entry.listeners.clear();
85
-
86
- for (const listener of listeners) {
87
- try {
88
- listener();
89
- } catch {
90
- // Cache refresh notifications are best-effort.
91
- }
92
- }
93
- }
94
-
95
- private evictOldestEntry(): void {
96
- if (this.entries.size <= this.maxEntries) return;
97
- const oldestKey = this.entries.keys().next().value;
98
- if (oldestKey !== undefined) this.entries.delete(oldestKey);
99
- }
100
-
101
- private cacheKey<K>(ns: CacheNamespace, key: K): string {
102
- return `${ns}:${String(key)}`;
103
- }
104
- }
105
-
106
- export const asyncCache = new AsyncCache();
@@ -1,237 +0,0 @@
1
- import type { Theme, ThemeColor } from "@earendil-works/pi-coding-agent";
2
- import { Chalk } from "chalk";
3
-
4
- const chalk = {
5
- level: 2,
6
- c: new Chalk({ level: 2 }),
7
- };
8
-
9
- export const COLOR_LEVEL_VALUES = ["truecolor", "ansi256", "ansi16", "none"] as const;
10
-
11
- export type ColorLevel = (typeof COLOR_LEVEL_VALUES)[number];
12
- export type ColorName =
13
- | "default"
14
- | "black"
15
- | "red"
16
- | "green"
17
- | "yellow"
18
- | "blue"
19
- | "magenta"
20
- | "cyan"
21
- | "white"
22
- | "brightBlack"
23
- | "brightRed"
24
- | "brightGreen"
25
- | "brightYellow"
26
- | "brightBlue"
27
- | "brightMagenta"
28
- | "brightCyan"
29
- | "brightWhite"
30
- | `ansi256:${number}`
31
- | `pi:${ThemeColor}`;
32
-
33
- interface ColorChoice {
34
- label: string;
35
- value: ColorName;
36
- }
37
-
38
- export const STANDARD_COLORS: ColorChoice[] = [
39
- { label: "Default", value: "default" },
40
- { label: "Black", value: "black" },
41
- { label: "Red", value: "red" },
42
- { label: "Green", value: "green" },
43
- { label: "Yellow", value: "yellow" },
44
- { label: "Blue", value: "blue" },
45
- { label: "Magenta", value: "magenta" },
46
- { label: "Cyan", value: "cyan" },
47
- { label: "White", value: "white" },
48
- { label: "Bright Black", value: "brightBlack" },
49
- { label: "Bright Red", value: "brightRed" },
50
- { label: "Bright Green", value: "brightGreen" },
51
- { label: "Bright Yellow", value: "brightYellow" },
52
- { label: "Bright Blue", value: "brightBlue" },
53
- { label: "Bright Magenta", value: "brightMagenta" },
54
- { label: "Bright Cyan", value: "brightCyan" },
55
- { label: "Bright White", value: "brightWhite" },
56
- ];
57
-
58
- const PI_THEME_COLORS: ThemeColor[] = [
59
- "accent",
60
- "border",
61
- "borderAccent",
62
- "borderMuted",
63
- "success",
64
- "error",
65
- "warning",
66
- "muted",
67
- "dim",
68
- "text",
69
- "thinkingText",
70
- "userMessageText",
71
- "customMessageText",
72
- "customMessageLabel",
73
- "toolTitle",
74
- "toolOutput",
75
- "toolDiffAdded",
76
- "toolDiffRemoved",
77
- "toolDiffContext",
78
- "syntaxType",
79
- "thinkingOff",
80
- "thinkingMinimal",
81
- "thinkingLow",
82
- "thinkingMedium",
83
- "thinkingHigh",
84
- "thinkingXhigh",
85
- "bashMode",
86
- ];
87
-
88
- const PI_FOREGROUND_COLORS: ColorChoice[] = PI_THEME_COLORS.map((color) => ({
89
- label: `Pi ${themeColorDisplayName(color)}`,
90
- value: `pi:${color}`,
91
- }));
92
-
93
- export const FOREGROUND_COLORS: ColorChoice[] = [...STANDARD_COLORS, ...PI_FOREGROUND_COLORS];
94
-
95
- const ANSI16_FG: Record<
96
- Exclude<ColorName, `ansi256:${number}` | `pi:${ThemeColor}`>,
97
- [number, number]
98
- > = {
99
- default: [39, 49],
100
- black: [30, 40],
101
- red: [31, 41],
102
- green: [32, 42],
103
- yellow: [33, 43],
104
- blue: [34, 44],
105
- magenta: [35, 45],
106
- cyan: [36, 46],
107
- white: [37, 47],
108
- brightBlack: [90, 100],
109
- brightRed: [91, 101],
110
- brightGreen: [92, 102],
111
- brightYellow: [93, 103],
112
- brightBlue: [94, 104],
113
- brightMagenta: [95, 105],
114
- brightCyan: [96, 106],
115
- brightWhite: [97, 107],
116
- };
117
-
118
- export function normalizeColor(value: unknown): ColorName | undefined {
119
- if (typeof value !== "string") return undefined;
120
- if (STANDARD_COLORS.some((color) => color.value === value)) return value as ColorName;
121
- if (PI_FOREGROUND_COLORS.some((color) => color.value === value)) return value as ColorName;
122
- const match = /^ansi256:([0-9]{1,3})$/.exec(value);
123
- if (!match) return undefined;
124
- const code = Number(match[1]);
125
- return Number.isInteger(code) && code >= 0 && code <= 255
126
- ? (`ansi256:${code}` as ColorName)
127
- : undefined;
128
- }
129
-
130
- export function colorDisplayName(color: ColorName | undefined): string {
131
- if (!color || color === "default") return "Default";
132
- if (color.startsWith("ansi256:")) return `ANSI256 ${color.slice("ansi256:".length)}`;
133
- if (color.startsWith("pi:"))
134
- return PI_FOREGROUND_COLORS.find((entry) => entry.value === color)?.label ?? color;
135
- return STANDARD_COLORS.find((entry) => entry.value === color)?.label ?? color;
136
- }
137
-
138
- export function ansi256Digits(color: ColorName | undefined): string {
139
- return color?.startsWith("ansi256:") ? String(Number(color.slice("ansi256:".length))) : "0";
140
- }
141
-
142
- export function appendAnsi256Digit(color: ColorName | undefined, digit: string): ColorName {
143
- const digits = ansi256Digits(color);
144
- const next = Number(`${digits}${digit}`);
145
- return `ansi256:${Math.min(255, next)}`;
146
- }
147
-
148
- export function deleteAnsi256Digit(color: ColorName | undefined): ColorName {
149
- const digits = ansi256Digits(color) || "0";
150
- const next = digits.slice(0, -1);
151
- return `ansi256:${next === "" ? 0 : Number(next)}`;
152
- }
153
-
154
- function useColorLevel(level: ColorLevel) {
155
- const next = level === "truecolor" ? 3 : level === "ansi256" ? 2 : 1;
156
- if (chalk.level === next) return;
157
- chalk.level = next;
158
- chalk.c = new Chalk({ level: next });
159
- }
160
-
161
- export function applyColors(
162
- text: string,
163
- foreground: ColorName | undefined,
164
- background: ColorName | undefined,
165
- bold: boolean | undefined,
166
- level: ColorLevel,
167
- theme?: Theme,
168
- ): string {
169
- if (level === "none") return text;
170
- useColorLevel(level);
171
-
172
- let output = text;
173
- if (foreground && foreground !== "default")
174
- output = applyOne(output, foreground, false, level, theme);
175
- if (background && background !== "default") output = applyOne(output, background, true, level);
176
- if (bold) output = chalk.c.bold(output);
177
- return output;
178
- }
179
-
180
- // The styleable color bag shared by widget options and the context conditional-color helper.
181
- // fg/bg are validated ColorName (color picker); the warning/danger quartet is raw text input
182
- // (kind: "text" properties) normalized via normalizeColor() at read time.
183
- export interface ConditionalColorFields {
184
- fg?: ColorName;
185
- bg?: ColorName;
186
- warningFg?: string;
187
- warningBg?: string;
188
- dangerFg?: string;
189
- dangerBg?: string;
190
- }
191
-
192
- export function resetAnsi256Colors<T extends ConditionalColorFields>(options: T): T {
193
- const next = { ...options };
194
- if (next.fg?.startsWith("ansi256:")) next.fg = "default";
195
- if (next.bg?.startsWith("ansi256:")) next.bg = "default";
196
- if (next.warningFg?.startsWith("ansi256:")) next.warningFg = "default";
197
- if (next.warningBg?.startsWith("ansi256:")) next.warningBg = "default";
198
- if (next.dangerFg?.startsWith("ansi256:")) next.dangerFg = "default";
199
- if (next.dangerBg?.startsWith("ansi256:")) next.dangerBg = "default";
200
- return next;
201
- }
202
-
203
- function themeColorDisplayName(color: ThemeColor): string {
204
- return color.replace(/([A-Z])/g, " $1").replace(/^./, (char) => char.toUpperCase());
205
- }
206
-
207
- function applyOne(
208
- text: string,
209
- color: ColorName,
210
- background: boolean,
211
- level: ColorLevel,
212
- theme?: Theme,
213
- ): string {
214
- if (color.startsWith("pi:")) {
215
- if (background || !theme) return text;
216
- return theme.fg(color.slice("pi:".length) as ThemeColor, text);
217
- }
218
- if (color.startsWith("ansi256:")) {
219
- const code = Number(color.slice("ansi256:".length));
220
- if (level === "ansi256" || level === "truecolor") {
221
- return background ? chalk.c.bgAnsi256(code)(text) : chalk.c.ansi256(code)(text);
222
- }
223
- return text;
224
- }
225
-
226
- const codes = ANSI16_FG[color as Exclude<ColorName, `ansi256:${number}` | `pi:${ThemeColor}`>];
227
- if (!codes || color === "default") return text;
228
- return `\x1b[${background ? codes[1] : codes[0]}m${text}\x1b[${background ? 49 : 39}m`;
229
- }
230
-
231
- // Keep the escape byte out of a regex literal so oxlint's no-control-regex rule does not
232
- // flag the intentional ANSI matcher. RegExp still receives the ESC sequence at runtime.
233
- const ANSI_ESCAPE_PATTERN = new RegExp(String.raw`\x1B\[[0-?]*[ -/]*[@-~]`, "g");
234
-
235
- export function stripAnsi(text: string): string {
236
- return text.replace(ANSI_ESCAPE_PATTERN, "");
237
- }
@@ -1,202 +0,0 @@
1
- import { mkdir, readFile, writeFile } from "node:fs/promises";
2
- import { dirname, join } from "node:path";
3
-
4
- import { getAgentDir } from "@earendil-works/pi-coding-agent";
5
-
6
- import type { ColorLevel } from "./colors.js";
7
- import { COLOR_LEVEL_VALUES, normalizeColor } from "./colors.js";
8
- import {
9
- cloneExtensionStatusRow,
10
- DEFAULT_EXTENSION_STATUS_ROW,
11
- normalizeExtensionStatusRow,
12
- } from "./extension-statuses.js";
13
- import {
14
- PRESET_DEFINITIONS,
15
- type Preset,
16
- type PresetDefinition,
17
- type PresetWidget,
18
- } from "./presets.js";
19
- import { SEPARATOR_VALUES, type SeparatorStyle } from "./separators.js";
20
- import type {
21
- IconMode,
22
- StatuslineConfig,
23
- StatuslineSettings,
24
- TerminalOptions,
25
- TerminalWidthMode,
26
- WidgetEntry,
27
- } from "./types.js";
28
- import { ICON_MODE_VALUES, isRecord, TERMINAL_WIDTH_MODE_VALUES } from "./types.js";
29
- import { registry, type WidgetType } from "./widgets/registry.js";
30
-
31
- export const STATUS_KEY = "pi-footer";
32
-
33
- const CONFIG_ENV = "PI_FOOTER_CONFIG";
34
- const DEFAULT_CONFIG_PATH = join(getAgentDir(), "extensions", "pi-footer.json");
35
- const SEPARATORS = new Set<SeparatorStyle>(SEPARATOR_VALUES);
36
-
37
- const DEFAULT_TERMINAL_OPTIONS: TerminalOptions = {
38
- widthMode: "full",
39
- colorLevel: "ansi256",
40
- };
41
-
42
- export const DEFAULT_CONFIG: StatuslineConfig = {
43
- version: 1,
44
- enabled: true,
45
- preset: "default",
46
- lines: linesForPreset("default"),
47
- separator: "dot",
48
- separatorFg: "default",
49
- separatorBg: "default",
50
- iconMode: "emoji",
51
- minimalist: false,
52
- terminal: DEFAULT_TERMINAL_OPTIONS,
53
- extensionStatusRow: DEFAULT_EXTENSION_STATUS_ROW,
54
- };
55
-
56
- export function getConfigPath(): string {
57
- return process.env[CONFIG_ENV] ?? DEFAULT_CONFIG_PATH;
58
- }
59
-
60
- function linesForPreset(preset: Preset): WidgetEntry[][] {
61
- return PRESET_DEFINITIONS[preset].lines.map((line) => widgetsFromPresetLine(line));
62
- }
63
-
64
- export function configWithPreset(config: StatuslineConfig, preset: Preset): StatuslineConfig {
65
- const definition: PresetDefinition = PRESET_DEFINITIONS[preset];
66
- return {
67
- ...config,
68
- preset,
69
- lines: linesForPreset(preset),
70
- separator: definition.separator ?? config.separator,
71
- iconMode: definition.iconMode ?? config.iconMode,
72
- terminal: { ...config.terminal, ...definition.terminal },
73
- };
74
- }
75
-
76
- function widgetsFromPresetLine(line: readonly PresetWidget[]): WidgetEntry[] {
77
- return line.map((widget) => registry.createEntry(widget.type, widget.options));
78
- }
79
-
80
- export function normalizeConfig(input: unknown): StatuslineConfig {
81
- if (!isRecord(input)) return cloneConfig(DEFAULT_CONFIG);
82
-
83
- const preset = isPreset(input.preset) ? input.preset : DEFAULT_CONFIG.preset;
84
- const lines = normalizeLines(input.lines, preset);
85
-
86
- return {
87
- version: 1,
88
- enabled: typeof input.enabled === "boolean" ? input.enabled : DEFAULT_CONFIG.enabled,
89
- preset,
90
- lines,
91
- separator: isSeparatorStyle(input.separator)
92
- ? input.separator
93
- : (PRESET_DEFINITIONS[preset].separator ?? DEFAULT_CONFIG.separator),
94
- separatorFg: normalizeColor(input.separatorFg) ?? DEFAULT_CONFIG.separatorFg,
95
- separatorBg: normalizeColor(input.separatorBg) ?? DEFAULT_CONFIG.separatorBg,
96
- iconMode: isIconMode(input.iconMode) ? input.iconMode : DEFAULT_CONFIG.iconMode,
97
- minimalist:
98
- typeof input.minimalist === "boolean" ? input.minimalist : DEFAULT_CONFIG.minimalist,
99
- terminal: normalizeTerminalOptions(input.terminal, PRESET_DEFINITIONS[preset].terminal),
100
- extensionStatusRow: normalizeExtensionStatusRow(input.extensionStatusRow),
101
- };
102
- }
103
-
104
- export function cloneSettings(settings: StatuslineSettings): StatuslineSettings {
105
- return {
106
- ...settings,
107
- terminal: { ...settings.terminal },
108
- extensionStatusRow: cloneExtensionStatusRow(settings.extensionStatusRow),
109
- };
110
- }
111
-
112
- export function cloneConfig(config: StatuslineConfig): StatuslineConfig {
113
- return {
114
- ...cloneSettings(config),
115
- lines: config.lines.map((line) =>
116
- line.map((widget) => ({ ...widget, options: { ...widget.options } })),
117
- ),
118
- };
119
- }
120
-
121
- export async function loadConfig(path = getConfigPath()): Promise<StatuslineConfig> {
122
- try {
123
- const raw = await readFile(path, "utf8");
124
- return normalizeConfig(JSON.parse(raw));
125
- } catch (error) {
126
- if (isNodeError(error) && error.code === "ENOENT") {
127
- return cloneConfig(DEFAULT_CONFIG);
128
- }
129
- throw error;
130
- }
131
- }
132
-
133
- export async function saveConfig(config: StatuslineConfig, path = getConfigPath()): Promise<void> {
134
- await mkdir(dirname(path), { recursive: true });
135
- await writeFile(path, `${JSON.stringify(normalizeConfig(config), null, 2)}\n`, "utf8");
136
- }
137
-
138
- function normalizeLines(linesValue: unknown, preset: Preset): WidgetEntry[][] {
139
- if (!Array.isArray(linesValue)) return linesForPreset(preset);
140
- return linesValue.map((line) => normalizeWidgets(line));
141
- }
142
-
143
- function normalizeWidgets(value: unknown): WidgetEntry[] {
144
- if (!Array.isArray(value)) return [];
145
-
146
- const widgets: WidgetEntry[] = [];
147
- for (const item of value) {
148
- if (!isRecord(item) || typeof item.type !== "string") continue;
149
- const spec = registry.maybeSpec(item.type);
150
- if (!spec) continue;
151
- widgets.push({
152
- id:
153
- typeof item.id === "string" && item.id.length > 0
154
- ? item.id
155
- : registry.createEntry(spec.type as WidgetType).id,
156
- type: spec.type as WidgetType,
157
- enabled: typeof item.enabled === "boolean" ? item.enabled : true,
158
- options: registry.normalizeOptions(
159
- spec.type as WidgetType,
160
- isRecord(item.options) ? item.options : {},
161
- ),
162
- });
163
- }
164
-
165
- return widgets;
166
- }
167
-
168
- function normalizeTerminalOptions(
169
- value: unknown,
170
- defaults: Partial<TerminalOptions> = {},
171
- ): TerminalOptions {
172
- const base = { ...DEFAULT_TERMINAL_OPTIONS, ...defaults };
173
- if (!isRecord(value)) return base;
174
- return {
175
- widthMode:
176
- typeof value.widthMode === "string" &&
177
- TERMINAL_WIDTH_MODE_VALUES.includes(value.widthMode as TerminalWidthMode)
178
- ? (value.widthMode as TerminalWidthMode)
179
- : base.widthMode,
180
- colorLevel:
181
- typeof value.colorLevel === "string" &&
182
- COLOR_LEVEL_VALUES.includes(value.colorLevel as ColorLevel)
183
- ? (value.colorLevel as ColorLevel)
184
- : base.colorLevel,
185
- };
186
- }
187
-
188
- export function isPreset(value: unknown): value is Preset {
189
- return typeof value === "string" && Object.hasOwn(PRESET_DEFINITIONS, value);
190
- }
191
-
192
- function isSeparatorStyle(value: unknown): value is SeparatorStyle {
193
- return typeof value === "string" && SEPARATORS.has(value as SeparatorStyle);
194
- }
195
-
196
- function isIconMode(value: unknown): value is IconMode {
197
- return typeof value === "string" && ICON_MODE_VALUES.includes(value as IconMode);
198
- }
199
-
200
- function isNodeError(error: unknown): error is NodeJS.ErrnoException {
201
- return error instanceof Error && "code" in error;
202
- }
@@ -1,41 +0,0 @@
1
- import { isRecord } from "./types.js";
2
-
3
- export const UPDATE_EVENT_WIDGET_EVENT = "pi-footer:update-widget";
4
-
5
- interface UpdateEventWidgetPayload {
6
- widgetId: string;
7
- value: string | null;
8
- }
9
-
10
- const EVENT_WIDGET_ID_PREFIX = "event_";
11
-
12
- export function createEventWidgetId(): string {
13
- return `${EVENT_WIDGET_ID_PREFIX}${Math.random().toString(36).slice(2, 10)}`;
14
- }
15
-
16
- export class EventWidgetValues {
17
- private readonly valuesById = new Map<string, string>();
18
-
19
- get values(): ReadonlyMap<string, string> {
20
- return this.valuesById;
21
- }
22
-
23
- update(payload: unknown): boolean {
24
- if (!isUpdatePayload(payload)) return false;
25
- if (payload.value === null) {
26
- return this.valuesById.delete(payload.widgetId);
27
- }
28
- const previous = this.valuesById.get(payload.widgetId);
29
- this.valuesById.set(payload.widgetId, payload.value);
30
- return previous !== payload.value;
31
- }
32
- }
33
-
34
- function isUpdatePayload(value: unknown): value is UpdateEventWidgetPayload {
35
- if (!isRecord(value)) return false;
36
- return (
37
- typeof value.widgetId === "string" &&
38
- value.widgetId.length > 0 &&
39
- (typeof value.value === "string" || value.value === null)
40
- );
41
- }
@@ -1,102 +0,0 @@
1
- import { isRecord } from "./types.js";
2
-
3
- export const EMPTY_STATUS_LABEL = "[Empty status]";
4
-
5
- export interface ExtensionStatusRowConfig {
6
- hiddenKeys: string[];
7
- knownKeys: string[];
8
- }
9
-
10
- interface ExtensionStatusEntry {
11
- key: string;
12
- value: string;
13
- published: boolean;
14
- }
15
-
16
- export type GetExtensionStatuses = () => ReadonlyMap<string, string>;
17
-
18
- export const DEFAULT_EXTENSION_STATUS_ROW: ExtensionStatusRowConfig = {
19
- hiddenKeys: [],
20
- knownKeys: [],
21
- };
22
-
23
- export const EMPTY_EXTENSION_STATUSES: ReadonlyMap<string, string> = new Map<string, string>();
24
-
25
- export function extensionStatusEntries(
26
- statuses: ReadonlyMap<string, string>,
27
- ownStatusKey: string,
28
- ): ExtensionStatusEntry[] {
29
- return [...statuses.entries()]
30
- .filter(([key, value]) => key !== ownStatusKey && value.length > 0)
31
- .sort(([left], [right]) => left.localeCompare(right))
32
- .map(([key, value]) => ({ key, value, published: true }));
33
- }
34
-
35
- export function allExtensionStatusEntries(
36
- statuses: ReadonlyMap<string, string>,
37
- rowConfig: ExtensionStatusRowConfig,
38
- ownStatusKey: string,
39
- ): ExtensionStatusEntry[] {
40
- const keys = new Set([...statuses.keys(), ...rowConfig.hiddenKeys, ...rowConfig.knownKeys]);
41
- return [...keys]
42
- .filter((key) => key.length > 0 && key !== ownStatusKey)
43
- .sort((left, right) => left.localeCompare(right))
44
- .map((key) => {
45
- const value = statuses.get(key) ?? "";
46
- return {
47
- key,
48
- value: value.length > 0 ? value : EMPTY_STATUS_LABEL,
49
- published: value.length > 0,
50
- };
51
- });
52
- }
53
-
54
- export function visibleExtensionStatusRowEntries(
55
- statuses: ReadonlyMap<string, string>,
56
- hiddenKeys: readonly string[],
57
- ownStatusKey: string,
58
- ): ExtensionStatusEntry[] {
59
- const hidden = new Set(hiddenKeys);
60
- return extensionStatusEntries(statuses, ownStatusKey).filter((entry) => !hidden.has(entry.key));
61
- }
62
-
63
- export function toggleExtensionStatusRowKey(
64
- rowConfig: ExtensionStatusRowConfig,
65
- key: string,
66
- ): ExtensionStatusRowConfig {
67
- const hidden = new Set(rowConfig.hiddenKeys);
68
- const known = new Set(rowConfig.knownKeys);
69
- known.add(key);
70
- if (hidden.has(key)) hidden.delete(key);
71
- else hidden.add(key);
72
- return {
73
- hiddenKeys: sortedKeys(hidden),
74
- knownKeys: sortedKeys(known),
75
- };
76
- }
77
-
78
- export function normalizeExtensionStatusRow(value: unknown): ExtensionStatusRowConfig {
79
- if (!isRecord(value)) return cloneExtensionStatusRow(DEFAULT_EXTENSION_STATUS_ROW);
80
- return {
81
- hiddenKeys: normalizeKeyList(value.hiddenKeys),
82
- knownKeys: normalizeKeyList(value.knownKeys),
83
- };
84
- }
85
-
86
- export function cloneExtensionStatusRow(value: ExtensionStatusRowConfig): ExtensionStatusRowConfig {
87
- return {
88
- hiddenKeys: [...value.hiddenKeys],
89
- knownKeys: [...value.knownKeys],
90
- };
91
- }
92
-
93
- function normalizeKeyList(value: unknown): string[] {
94
- if (!Array.isArray(value)) return [];
95
- return sortedKeys(
96
- new Set(value.filter((key): key is string => typeof key === "string" && key.length > 0)),
97
- );
98
- }
99
-
100
- function sortedKeys(keys: Iterable<string>): string[] {
101
- return [...keys].sort((left, right) => left.localeCompare(right));
102
- }