dexterm-cli 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (327) hide show
  1. package/dist/packages/agents/src/bus.js +37 -1
  2. package/dist/packages/agents/src/follow.js +105 -0
  3. package/dist/packages/agents/src/index.js +5 -0
  4. package/dist/packages/agents/src/spectator-server.js +153 -0
  5. package/dist/packages/agents/src/spectator.js +212 -0
  6. package/dist/packages/cli/assets/claude/analyst-system.md +7 -1
  7. package/dist/packages/cli/src/agent-cmd.js +71 -7
  8. package/dist/packages/cli/src/agent-spectator.js +37 -0
  9. package/dist/packages/cli/src/alerts/format.js +25 -0
  10. package/dist/packages/cli/src/app-help-gen.js +365 -0
  11. package/dist/packages/cli/src/docs-kb-gen.js +228 -0
  12. package/dist/packages/cli/src/doctor.js +28 -12
  13. package/dist/packages/cli/src/follow-cmd.js +107 -1
  14. package/dist/packages/cli/src/help-cmd.js +48 -0
  15. package/dist/packages/cli/src/index.js +1 -1
  16. package/dist/packages/cli/src/kb-skill-cmd.js +3 -0
  17. package/dist/packages/cli/src/larp-detected.js +209 -0
  18. package/dist/packages/cli/src/live/index.js +64 -3
  19. package/dist/packages/cli/src/live/screens/token-live.js +24 -0
  20. package/dist/packages/cli/src/live/signals.js +109 -0
  21. package/dist/packages/cli/src/live/token.js +38 -1
  22. package/dist/packages/cli/src/live/trade.js +24 -1
  23. package/dist/packages/cli/src/main.js +495 -11
  24. package/dist/packages/cli/src/mcp-cmd.js +2 -7
  25. package/dist/packages/cli/src/mcp-follow.js +225 -0
  26. package/dist/packages/cli/src/pnl-app.js +221 -0
  27. package/dist/packages/cli/src/pnl-card.js +615 -0
  28. package/dist/packages/cli/src/record-cmd.js +455 -0
  29. package/dist/packages/cli/src/rules.js +50 -2
  30. package/dist/packages/cli/src/screens/follows.js +91 -2
  31. package/dist/packages/cli/src/screens/overlay.js +3 -0
  32. package/dist/packages/cli/src/screens/positions.js +1 -1
  33. package/dist/packages/cli/src/screens/rules.js +1 -1
  34. package/dist/packages/cli/src/spectate-cmd.js +115 -0
  35. package/dist/packages/cli/src/state.js +1 -1
  36. package/dist/packages/cli/src/version.js +1 -1
  37. package/dist/packages/cli/src/voice-cmd.js +86 -11
  38. package/dist/packages/cli/src/voice-hud.js +1 -1
  39. package/dist/packages/cli/src/x-cmd.js +11 -5
  40. package/dist/packages/custom/src/rules.js +2 -1
  41. package/dist/packages/data/src/analyst-actions.js +130 -3
  42. package/dist/packages/data/src/fast-lane.js +16 -2
  43. package/dist/packages/data/src/index.js +1 -0
  44. package/dist/packages/data/src/intel/live-signals.js +185 -0
  45. package/dist/packages/data/src/trade/copy/index.js +1 -1
  46. package/dist/packages/data/src/trade/copy/stats.js +36 -2
  47. package/dist/packages/data/src/trade/copy/tracker.js +3 -2
  48. package/dist/packages/mcp/assets/kb/app-help/app-help-command.md +35 -0
  49. package/dist/packages/mcp/assets/kb/app-help/ask-the-analyst.md +43 -0
  50. package/dist/packages/mcp/assets/kb/app-help/backtest.md +33 -0
  51. package/dist/packages/mcp/assets/kb/app-help/bubble-map.md +35 -0
  52. package/dist/packages/mcp/assets/kb/app-help/calm-mode.md +31 -0
  53. package/dist/packages/mcp/assets/kb/app-help/change-voice-speed.md +31 -0
  54. package/dist/packages/mcp/assets/kb/app-help/change-voice.md +30 -0
  55. package/dist/packages/mcp/assets/kb/app-help/chart-popup-selftest.md +32 -0
  56. package/dist/packages/mcp/assets/kb/app-help/coin-images.md +29 -0
  57. package/dist/packages/mcp/assets/kb/app-help/configure-rpc-key.md +28 -0
  58. package/dist/packages/mcp/assets/kb/app-help/connect-an-agent-registry.md +35 -0
  59. package/dist/packages/mcp/assets/kb/app-help/connect-an-agent.md +39 -0
  60. package/dist/packages/mcp/assets/kb/app-help/custom-keymap.md +32 -0
  61. package/dist/packages/mcp/assets/kb/app-help/edit-kb-or-skill.md +36 -0
  62. package/dist/packages/mcp/assets/kb/app-help/edit-rules.md +34 -0
  63. package/dist/packages/mcp/assets/kb/app-help/export-a-view.md +36 -0
  64. package/dist/packages/mcp/assets/kb/app-help/follow-a-wallet.md +33 -0
  65. package/dist/packages/mcp/assets/kb/app-help/getting-started.md +37 -0
  66. package/dist/packages/mcp/assets/kb/app-help/kol-lists.md +34 -0
  67. package/dist/packages/mcp/assets/kb/app-help/larp-check.md +36 -0
  68. package/dist/packages/mcp/assets/kb/app-help/link-a-wallet.md +41 -0
  69. package/dist/packages/mcp/assets/kb/app-help/login-with-x.md +33 -0
  70. package/dist/packages/mcp/assets/kb/app-help/narrative-board.md +32 -0
  71. package/dist/packages/mcp/assets/kb/app-help/open-a-coin.md +43 -0
  72. package/dist/packages/mcp/assets/kb/app-help/open-chart-popup.md +33 -0
  73. package/dist/packages/mcp/assets/kb/app-help/order-plans.md +33 -0
  74. package/dist/packages/mcp/assets/kb/app-help/paper-trade.md +36 -0
  75. package/dist/packages/mcp/assets/kb/app-help/price-or-marketcap.md +38 -0
  76. package/dist/packages/mcp/assets/kb/app-help/record-headless.md +34 -0
  77. package/dist/packages/mcp/assets/kb/app-help/recorder-history.md +39 -0
  78. package/dist/packages/mcp/assets/kb/app-help/rug-check.md +39 -0
  79. package/dist/packages/mcp/assets/kb/app-help/run-doctor.md +32 -0
  80. package/dist/packages/mcp/assets/kb/app-help/scan-mode.md +37 -0
  81. package/dist/packages/mcp/assets/kb/app-help/screen-analyst.md +181 -0
  82. package/dist/packages/mcp/assets/kb/app-help/screen-kol.md +190 -0
  83. package/dist/packages/mcp/assets/kb/app-help/screen-newpairs.md +181 -0
  84. package/dist/packages/mcp/assets/kb/app-help/screen-positions.md +180 -0
  85. package/dist/packages/mcp/assets/kb/app-help/screen-screener.md +199 -0
  86. package/dist/packages/mcp/assets/kb/app-help/screen-token.md +240 -0
  87. package/dist/packages/mcp/assets/kb/app-help/screen-trending.md +192 -0
  88. package/dist/packages/mcp/assets/kb/app-help/screen-watchlist.md +181 -0
  89. package/dist/packages/mcp/assets/kb/app-help/set-a-filter.md +36 -0
  90. package/dist/packages/mcp/assets/kb/app-help/setup-neural-voice.md +36 -0
  91. package/dist/packages/mcp/assets/kb/app-help/share-packs.md +34 -0
  92. package/dist/packages/mcp/assets/kb/app-help/sort-the-screener.md +34 -0
  93. package/dist/packages/mcp/assets/kb/app-help/spectate-an-agent.md +39 -0
  94. package/dist/packages/mcp/assets/kb/app-help/standing-mandates.md +33 -0
  95. package/dist/packages/mcp/assets/kb/app-help/switch-theme.md +42 -0
  96. package/dist/packages/mcp/assets/kb/app-help/turn-on-alerts.md +37 -0
  97. package/dist/packages/mcp/assets/kb/app-help/update-dexterm.md +30 -0
  98. package/dist/packages/mcp/assets/kb/app-help/use-presets.md +42 -0
  99. package/dist/packages/mcp/assets/kb/app-help/use-voice-mode.md +36 -0
  100. package/dist/packages/mcp/assets/kb/app-help/watch-a-coin.md +34 -0
  101. package/dist/packages/mcp/assets/kb/app-help/watch-headless.md +35 -0
  102. package/dist/packages/mcp/assets/kb/app-help/what-dexterm-shows-agents.md +31 -0
  103. package/dist/packages/mcp/assets/kb/app-help/workspaces.md +38 -0
  104. package/dist/packages/mcp/assets/kb/docs/docs-agents-capability-tiers-enforced-server-side.md +38 -0
  105. package/dist/packages/mcp/assets/kb/docs/docs-agents-install-in-one-command.md +49 -0
  106. package/dist/packages/mcp/assets/kb/docs/docs-agents-per-agent-mandates.md +35 -0
  107. package/dist/packages/mcp/assets/kb/docs/docs-agents-recipes.md +43 -0
  108. package/dist/packages/mcp/assets/kb/docs/docs-agents-red-team-coverage.md +30 -0
  109. package/dist/packages/mcp/assets/kb/docs/docs-agents-two-ways-to-connect.md +37 -0
  110. package/dist/packages/mcp/assets/kb/docs/docs-agents-untrusted-by-default.md +36 -0
  111. package/dist/packages/mcp/assets/kb/docs/docs-agents-watch-an-agent-work-spectator-view.md +35 -0
  112. package/dist/packages/mcp/assets/kb/docs/docs-agents.md +26 -0
  113. package/dist/packages/mcp/assets/kb/docs/docs-analyst-answer-style.md +35 -0
  114. package/dist/packages/mcp/assets/kb/docs/docs-analyst-if-claude-is-missing.md +25 -0
  115. package/dist/packages/mcp/assets/kb/docs/docs-analyst-it-knows-the-app.md +33 -0
  116. package/dist/packages/mcp/assets/kb/docs/docs-analyst-mcp-tools.md +33 -0
  117. package/dist/packages/mcp/assets/kb/docs/docs-analyst-plain-language-filters.md +25 -0
  118. package/dist/packages/mcp/assets/kb/docs/docs-analyst-skills.md +31 -0
  119. package/dist/packages/mcp/assets/kb/docs/docs-analyst-starting-a-run.md +33 -0
  120. package/dist/packages/mcp/assets/kb/docs/docs-analyst-what-it-can-change-three-tiers.md +33 -0
  121. package/dist/packages/mcp/assets/kb/docs/docs-analyst-what-it-sees.md +26 -0
  122. package/dist/packages/mcp/assets/kb/docs/docs-analyst-what-the-analyst-can-never-do.md +31 -0
  123. package/dist/packages/mcp/assets/kb/docs/docs-analyst.md +23 -0
  124. package/dist/packages/mcp/assets/kb/docs/docs-beginners-1-start-dexterm.md +35 -0
  125. package/dist/packages/mcp/assets/kb/docs/docs-beginners-2-open-a-real-coin-by-contract-address.md +43 -0
  126. package/dist/packages/mcp/assets/kb/docs/docs-beginners-3-read-the-safety-panel.md +40 -0
  127. package/dist/packages/mcp/assets/kb/docs/docs-beginners-4-read-the-holder-panel.md +35 -0
  128. package/dist/packages/mcp/assets/kb/docs/docs-beginners-5-optionally-ask-the-analyst.md +39 -0
  129. package/dist/packages/mcp/assets/kb/docs/docs-beginners-6-export-or-share-what-you-see.md +34 -0
  130. package/dist/packages/mcp/assets/kb/docs/docs-beginners-7-quit-safely.md +34 -0
  131. package/dist/packages/mcp/assets/kb/docs/docs-beginners-before-any-experimental-trading.md +33 -0
  132. package/dist/packages/mcp/assets/kb/docs/docs-beginners-check-the-installation-with-doctor.md +38 -0
  133. package/dist/packages/mcp/assets/kb/docs/docs-beginners-choose-a-setup-path.md +30 -0
  134. package/dist/packages/mcp/assets/kb/docs/docs-beginners-common-mistakes-and-recovery.md +30 -0
  135. package/dist/packages/mcp/assets/kb/docs/docs-beginners-copy-and-paste-without-surprises.md +39 -0
  136. package/dist/packages/mcp/assets/kb/docs/docs-beginners-if-data-says-unavailable-stale-or-rate-limited.md +35 -0
  137. package/dist/packages/mcp/assets/kb/docs/docs-beginners-if-dexterm-says-command-not-found.md +36 -0
  138. package/dist/packages/mcp/assets/kb/docs/docs-beginners-if-optional-help-is-unavailable.md +33 -0
  139. package/dist/packages/mcp/assets/kb/docs/docs-beginners-if-paste-does-nothing-or-pastes-twice.md +35 -0
  140. package/dist/packages/mcp/assets/kb/docs/docs-beginners-if-the-screen-looks-broken.md +33 -0
  141. package/dist/packages/mcp/assets/kb/docs/docs-beginners-if-you-typed-the-wrong-thing.md +33 -0
  142. package/dist/packages/mcp/assets/kb/docs/docs-beginners-install-node-js-first.md +36 -0
  143. package/dist/packages/mcp/assets/kb/docs/docs-beginners-linux.md +30 -0
  144. package/dist/packages/mcp/assets/kb/docs/docs-beginners-macos-homebrew.md +46 -0
  145. package/dist/packages/mcp/assets/kb/docs/docs-beginners-macos-or-linux-npm.md +39 -0
  146. package/dist/packages/mcp/assets/kb/docs/docs-beginners-macos.md +30 -0
  147. package/dist/packages/mcp/assets/kb/docs/docs-beginners-open-the-terminal.md +29 -0
  148. package/dist/packages/mcp/assets/kb/docs/docs-beginners-reopen-dexterm-later.md +36 -0
  149. package/dist/packages/mcp/assets/kb/docs/docs-beginners-ten-minute-first-win.md +30 -0
  150. package/dist/packages/mcp/assets/kb/docs/docs-beginners-terminal-shell-prompt-command-output-and-path.md +40 -0
  151. package/dist/packages/mcp/assets/kb/docs/docs-beginners-where-to-go-next.md +32 -0
  152. package/dist/packages/mcp/assets/kb/docs/docs-beginners-windows-expectations.md +29 -0
  153. package/dist/packages/mcp/assets/kb/docs/docs-beginners-windows-powershell-experimental.md +39 -0
  154. package/dist/packages/mcp/assets/kb/docs/docs-beginners-windows.md +30 -0
  155. package/dist/packages/mcp/assets/kb/docs/docs-beginners.md +29 -0
  156. package/dist/packages/mcp/assets/kb/docs/docs-cli-dexterm-help.md +31 -0
  157. package/dist/packages/mcp/assets/kb/docs/docs-cli-filter-grammar.md +37 -0
  158. package/dist/packages/mcp/assets/kb/docs/docs-cli-flags.md +27 -0
  159. package/dist/packages/mcp/assets/kb/docs/docs-cli-invocations.md +43 -0
  160. package/dist/packages/mcp/assets/kb/docs/docs-cli-presets.md +26 -0
  161. package/dist/packages/mcp/assets/kb/docs/docs-cli-scan-commands.md +26 -0
  162. package/dist/packages/mcp/assets/kb/docs/docs-cli-sort-keys.md +27 -0
  163. package/dist/packages/mcp/assets/kb/docs/docs-cli-subcommands.md +26 -0
  164. package/dist/packages/mcp/assets/kb/docs/docs-cli.md +25 -0
  165. package/dist/packages/mcp/assets/kb/docs/docs-configuration-environment-variables.md +45 -0
  166. package/dist/packages/mcp/assets/kb/docs/docs-configuration-files-on-disk.md +41 -0
  167. package/dist/packages/mcp/assets/kb/docs/docs-configuration-headless-recorder-dexterm-record.md +44 -0
  168. package/dist/packages/mcp/assets/kb/docs/docs-configuration-history-recorder.md +33 -0
  169. package/dist/packages/mcp/assets/kb/docs/docs-configuration-packs.md +38 -0
  170. package/dist/packages/mcp/assets/kb/docs/docs-configuration-price-display-mode.md +35 -0
  171. package/dist/packages/mcp/assets/kb/docs/docs-configuration-push-alerts-and-dexterm-watch.md +45 -0
  172. package/dist/packages/mcp/assets/kb/docs/docs-configuration-rules-engine.md +36 -0
  173. package/dist/packages/mcp/assets/kb/docs/docs-configuration-the-analyst-s-launch.md +27 -0
  174. package/dist/packages/mcp/assets/kb/docs/docs-configuration-the-optional-free-rpc-key.md +42 -0
  175. package/dist/packages/mcp/assets/kb/docs/docs-configuration-themes-and-keymaps.md +29 -0
  176. package/dist/packages/mcp/assets/kb/docs/docs-configuration-themes-and-look.md +27 -0
  177. package/dist/packages/mcp/assets/kb/docs/docs-configuration-widgets.md +31 -0
  178. package/dist/packages/mcp/assets/kb/docs/docs-configuration-workspaces.md +30 -0
  179. package/dist/packages/mcp/assets/kb/docs/docs-configuration.md +25 -0
  180. package/dist/packages/mcp/assets/kb/docs/docs-copy-trading-stage-1-follow-a-wallet-see-what-it-does.md +51 -0
  181. package/dist/packages/mcp/assets/kb/docs/docs-copy-trading-stage-2-the-one-key-mirror-ticket-a-proposal.md +56 -0
  182. package/dist/packages/mcp/assets/kb/docs/docs-copy-trading-stage-3-capped-auto-mirror-default-off-less.md +47 -0
  183. package/dist/packages/mcp/assets/kb/docs/docs-copy-trading-what-is-proven-what-is-not.md +36 -0
  184. package/dist/packages/mcp/assets/kb/docs/docs-copy-trading.md +31 -0
  185. package/dist/packages/mcp/assets/kb/docs/docs-data-sources-cache.md +32 -0
  186. package/dist/packages/mcp/assets/kb/docs/docs-data-sources-health-registry.md +29 -0
  187. package/dist/packages/mcp/assets/kb/docs/docs-data-sources-rate-limits-and-pacing.md +32 -0
  188. package/dist/packages/mcp/assets/kb/docs/docs-data-sources-request-budget-meter.md +30 -0
  189. package/dist/packages/mcp/assets/kb/docs/docs-data-sources-sources.md +47 -0
  190. package/dist/packages/mcp/assets/kb/docs/docs-data-sources-the-helius-credit-meter.md +30 -0
  191. package/dist/packages/mcp/assets/kb/docs/docs-data-sources.md +27 -0
  192. package/dist/packages/mcp/assets/kb/docs/docs-getting-started-dexterm-doctor.md +33 -0
  193. package/dist/packages/mcp/assets/kb/docs/docs-getting-started-first-run.md +34 -0
  194. package/dist/packages/mcp/assets/kb/docs/docs-getting-started-install.md +71 -0
  195. package/dist/packages/mcp/assets/kb/docs/docs-getting-started-next.md +32 -0
  196. package/dist/packages/mcp/assets/kb/docs/docs-getting-started-requirements.md +35 -0
  197. package/dist/packages/mcp/assets/kb/docs/docs-getting-started-running-the-tests.md +34 -0
  198. package/dist/packages/mcp/assets/kb/docs/docs-getting-started-supported-platforms.md +44 -0
  199. package/dist/packages/mcp/assets/kb/docs/docs-getting-started-updating.md +28 -0
  200. package/dist/packages/mcp/assets/kb/docs/docs-getting-started.md +27 -0
  201. package/dist/packages/mcp/assets/kb/docs/docs-keyboard-global-keys.md +26 -0
  202. package/dist/packages/mcp/assets/kb/docs/docs-keyboard-keys-handled-by-the-loop.md +29 -0
  203. package/dist/packages/mcp/assets/kb/docs/docs-keyboard-per-screen-keys.md +26 -0
  204. package/dist/packages/mcp/assets/kb/docs/docs-keyboard-what-shows.md +27 -0
  205. package/dist/packages/mcp/assets/kb/docs/docs-keyboard.md +26 -0
  206. package/dist/packages/mcp/assets/kb/docs/docs-larp-measured-accuracy.md +55 -0
  207. package/dist/packages/mcp/assets/kb/docs/docs-larp-open-link-keys.md +26 -0
  208. package/dist/packages/mcp/assets/kb/docs/docs-larp-paste-a-coin-on-the-web.md +35 -0
  209. package/dist/packages/mcp/assets/kb/docs/docs-larp-the-verdict.md +29 -0
  210. package/dist/packages/mcp/assets/kb/docs/docs-larp-timestamped-follow-up-drafts.md +35 -0
  211. package/dist/packages/mcp/assets/kb/docs/docs-larp-what-it-looks-at.md +33 -0
  212. package/dist/packages/mcp/assets/kb/docs/docs-larp.md +24 -0
  213. package/dist/packages/mcp/assets/kb/docs/docs-login-with-x-degraded-states-you-will-see.md +36 -0
  214. package/dist/packages/mcp/assets/kb/docs/docs-login-with-x-free-vs-paid-x-api-tiers-your-bill-your-limits.md +37 -0
  215. package/dist/packages/mcp/assets/kb/docs/docs-login-with-x-kol-lists-and-the-per-handle-filter.md +28 -0
  216. package/dist/packages/mcp/assets/kb/docs/docs-login-with-x-tests.md +25 -0
  217. package/dist/packages/mcp/assets/kb/docs/docs-login-with-x-what-is-read-and-when.md +35 -0
  218. package/dist/packages/mcp/assets/kb/docs/docs-login-with-x-what-you-set-up-once.md +40 -0
  219. package/dist/packages/mcp/assets/kb/docs/docs-login-with-x-where-the-tokens-live.md +27 -0
  220. package/dist/packages/mcp/assets/kb/docs/docs-login-with-x.md +26 -0
  221. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-a-live-ticket.md +42 -0
  222. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-before-you-press-size-vs-caps.md +34 -0
  223. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-devnet-signer-mainnet-token.md +35 -0
  224. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-jupiter-rate-limits.md +33 -0
  225. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-link-a-wallet.md +32 -0
  226. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-live-trading-devnet-first.md +30 -0
  227. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-mainnet.md +31 -0
  228. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-order-plans-and-standing-mandates.md +44 -0
  229. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-panic.md +31 -0
  230. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-pnl-cards.md +37 -0
  231. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-the-live-fire-path-devnet-the-fast-wallet.md +41 -0
  232. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-the-signer-process.md +34 -0
  233. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-the-ticket.md +31 -0
  234. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-the-wallet.md +34 -0
  235. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-trade-moments.md +32 -0
  236. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-what-the-live-path-keeps.md +37 -0
  237. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-your-first-live-trade.md +41 -0
  238. package/dist/packages/mcp/assets/kb/docs/docs-paper-trading.md +32 -0
  239. package/dist/packages/mcp/assets/kb/docs/docs-popup-chart-bubble-map-popup.md +27 -0
  240. package/dist/packages/mcp/assets/kb/docs/docs-popup-chart-build-the-native-window.md +33 -0
  241. package/dist/packages/mcp/assets/kb/docs/docs-popup-chart-config-dexterm-popup-json.md +38 -0
  242. package/dist/packages/mcp/assets/kb/docs/docs-popup-chart-docking-macos.md +27 -0
  243. package/dist/packages/mcp/assets/kb/docs/docs-popup-chart-keys-in-the-popup.md +30 -0
  244. package/dist/packages/mcp/assets/kb/docs/docs-popup-chart-market-cap-axis.md +28 -0
  245. package/dist/packages/mcp/assets/kb/docs/docs-popup-chart-security-model.md +33 -0
  246. package/dist/packages/mcp/assets/kb/docs/docs-popup-chart-token-and-feeds-popups.md +38 -0
  247. package/dist/packages/mcp/assets/kb/docs/docs-popup-chart-what-it-shows.md +30 -0
  248. package/dist/packages/mcp/assets/kb/docs/docs-popup-chart.md +27 -0
  249. package/dist/packages/mcp/assets/kb/docs/docs-scan-cost-control.md +28 -0
  250. package/dist/packages/mcp/assets/kb/docs/docs-scan-keys-flag-command.md +34 -0
  251. package/dist/packages/mcp/assets/kb/docs/docs-scan-safety-four-layers.md +32 -0
  252. package/dist/packages/mcp/assets/kb/docs/docs-scan-states.md +27 -0
  253. package/dist/packages/mcp/assets/kb/docs/docs-scan-the-read.md +25 -0
  254. package/dist/packages/mcp/assets/kb/docs/docs-scan-triggers-and-score.md +37 -0
  255. package/dist/packages/mcp/assets/kb/docs/docs-scan.md +24 -0
  256. package/dist/packages/mcp/assets/kb/docs/docs-scorecard-frozen-canary.md +30 -0
  257. package/dist/packages/mcp/assets/kb/docs/docs-scorecard-frozen-task-1401-evaluation.md +35 -0
  258. package/dist/packages/mcp/assets/kb/docs/docs-scorecard-latest-skill-care-run.md +33 -0
  259. package/dist/packages/mcp/assets/kb/docs/docs-scorecard-links-only-larp-baseline-where-it-is-weak.md +35 -0
  260. package/dist/packages/mcp/assets/kb/docs/docs-scorecard-not-measured.md +29 -0
  261. package/dist/packages/mcp/assets/kb/docs/docs-scorecard-rug-verdict-rules.md +33 -0
  262. package/dist/packages/mcp/assets/kb/docs/docs-scorecard-source-and-rebuild.md +31 -0
  263. package/dist/packages/mcp/assets/kb/docs/docs-scorecard.md +27 -0
  264. package/dist/packages/mcp/assets/kb/docs/docs-screens-1-screener.md +35 -0
  265. package/dist/packages/mcp/assets/kb/docs/docs-screens-2-new-pairs.md +28 -0
  266. package/dist/packages/mcp/assets/kb/docs/docs-screens-3-watchlist.md +27 -0
  267. package/dist/packages/mcp/assets/kb/docs/docs-screens-4-analyst-tab.md +28 -0
  268. package/dist/packages/mcp/assets/kb/docs/docs-screens-bubble-map.md +32 -0
  269. package/dist/packages/mcp/assets/kb/docs/docs-screens-coin-images.md +32 -0
  270. package/dist/packages/mcp/assets/kb/docs/docs-screens-live-holder-and-rug-signals.md +51 -0
  271. package/dist/packages/mcp/assets/kb/docs/docs-screens-order-plans.md +26 -0
  272. package/dist/packages/mcp/assets/kb/docs/docs-screens-paper-ticket-and-positions.md +29 -0
  273. package/dist/packages/mcp/assets/kb/docs/docs-screens-the-look.md +29 -0
  274. package/dist/packages/mcp/assets/kb/docs/docs-screens-token-screen.md +36 -0
  275. package/dist/packages/mcp/assets/kb/docs/docs-screens-trending-social-and-kol-lists.md +34 -0
  276. package/dist/packages/mcp/assets/kb/docs/docs-screens.md +26 -0
  277. package/dist/packages/mcp/assets/kb/docs/docs-spectator-1-the-agent-activity-window-follow-mode.md +56 -0
  278. package/dist/packages/mcp/assets/kb/docs/docs-spectator-2-the-read-only-stream-spectate.md +42 -0
  279. package/dist/packages/mcp/assets/kb/docs/docs-spectator-3-save-and-replay-record-file-dexterm-spectate.md +41 -0
  280. package/dist/packages/mcp/assets/kb/docs/docs-spectator-follow-over-mcp-in-the-running-terminal.md +39 -0
  281. package/dist/packages/mcp/assets/kb/docs/docs-spectator-limits.md +36 -0
  282. package/dist/packages/mcp/assets/kb/docs/docs-spectator-quick-start.md +37 -0
  283. package/dist/packages/mcp/assets/kb/docs/docs-spectator-security-model.md +35 -0
  284. package/dist/packages/mcp/assets/kb/docs/docs-spectator-see-also.md +29 -0
  285. package/dist/packages/mcp/assets/kb/docs/docs-spectator-streaming-it.md +32 -0
  286. package/dist/packages/mcp/assets/kb/docs/docs-spectator-the-three-surfaces.md +37 -0
  287. package/dist/packages/mcp/assets/kb/docs/docs-spectator-what-is-redacted.md +35 -0
  288. package/dist/packages/mcp/assets/kb/docs/docs-spectator.md +29 -0
  289. package/dist/packages/mcp/assets/kb/docs/docs-troubleshooting-common-questions.md +33 -0
  290. package/dist/packages/mcp/assets/kb/docs/docs-troubleshooting-doctor-lines.md +36 -0
  291. package/dist/packages/mcp/assets/kb/docs/docs-troubleshooting-in-app-messages.md +42 -0
  292. package/dist/packages/mcp/assets/kb/docs/docs-troubleshooting-reporting-a-problem.md +25 -0
  293. package/dist/packages/mcp/assets/kb/docs/docs-troubleshooting.md +23 -0
  294. package/dist/packages/mcp/assets/kb/docs/docs-voice-doctor.md +26 -0
  295. package/dist/packages/mcp/assets/kb/docs/docs-voice-it-clarifies-it-never-guesses.md +36 -0
  296. package/dist/packages/mcp/assets/kb/docs/docs-voice-latency.md +38 -0
  297. package/dist/packages/mcp/assets/kb/docs/docs-voice-linux-and-windows.md +32 -0
  298. package/dist/packages/mcp/assets/kb/docs/docs-voice-privacy.md +26 -0
  299. package/dist/packages/mcp/assets/kb/docs/docs-voice-still-unverified.md +27 -0
  300. package/dist/packages/mcp/assets/kb/docs/docs-voice-the-voice-neural-by-default.md +48 -0
  301. package/dist/packages/mcp/assets/kb/docs/docs-voice-what-it-can-never-do.md +27 -0
  302. package/dist/packages/mcp/assets/kb/docs/docs-voice-what-you-can-say.md +38 -0
  303. package/dist/packages/mcp/assets/kb/docs/docs-voice.md +25 -0
  304. package/dist/packages/mcp/src/app-help.js +258 -0
  305. package/dist/packages/mcp/src/firewall.js +2 -2
  306. package/dist/packages/mcp/src/index.js +5 -1
  307. package/dist/packages/mcp/src/server.js +129 -4
  308. package/dist/packages/mcp/src/spectator-sink.js +144 -0
  309. package/dist/packages/packs/src/index.js +2 -0
  310. package/dist/packages/packs/src/skill-care.js +206 -0
  311. package/dist/packages/popup/src/pages/spectator.css +45 -0
  312. package/dist/packages/popup/src/pages/spectator.html +25 -0
  313. package/dist/packages/popup/src/pages/spectator.js +74 -0
  314. package/dist/packages/popup/src/selftest.js +19 -0
  315. package/dist/packages/popup/src/server.js +7 -1
  316. package/dist/packages/tui/src/keymap.js +10 -0
  317. package/dist/packages/voice/src/controller.js +42 -1
  318. package/dist/packages/voice/src/doctor.js +25 -8
  319. package/dist/packages/voice/src/engines.js +8 -1
  320. package/dist/packages/voice/src/index.js +3 -1
  321. package/dist/packages/voice/src/speakable.js +111 -0
  322. package/dist/packages/voice/src/stt/whisper.js +4 -2
  323. package/dist/packages/voice/src/tts/piper-setup.js +229 -0
  324. package/dist/packages/voice/src/tts/piper.js +309 -66
  325. package/dist/packages/voice/src/tts/say.js +3 -2
  326. package/dist/packages/voice/src/tts/voices.js +8 -5
  327. package/package.json +6 -5
@@ -0,0 +1,48 @@
1
+ ---
2
+ id: docs-voice-the-voice-neural-by-default
3
+ title: Jarvis voice mode › The voice: neural by default
4
+ kind: docs
5
+ page: voice
6
+ page_title: Jarvis voice mode
7
+ heading: The voice: neural by default
8
+ anchor: the-voice-neural-by-default
9
+ url: https://dexterm.xyz/docs/voice#the-voice-neural-by-default
10
+ tags:
11
+ - docs
12
+ - voice
13
+ - neural
14
+ - default
15
+ - jarvis
16
+ - mode
17
+ confidence: high
18
+ owner: maintainers
19
+ origin: docs-generated
20
+ reviewed_by: generated@2026-10-16
21
+ generated_from: dexterm/site content/docs (task-1420)
22
+ sources:
23
+ - site/content/docs/voice.md
24
+ date: 2026-10-16
25
+ ---
26
+
27
+ dexterm speaks with a **neural British voice** (Piper, `en_GB-alan-medium`) — the one chosen as the default. It is free, local and keyless, and sounds markedly more natural than the built-in system voices. It is the default speaking voice everywhere it is installed, on macOS as well as Linux, with the system `say` voice as the fallback.
28
+
29
+ On macOS, run `dexterm voice setup` once to install it. The prebuilt macOS Piper binary from upstream is broken (it needs a system library it does not bundle), so dexterm instead builds its own private Python environment under `~/.dexterm/piper/` and installs Piper into it, then downloads the ~61 MB voice from the official source and checks it against a pinned checksum. It asks before it does any of this, needs Python 3.9+ (the doctor prints the exact install line if it is missing), runs fully offline afterwards, and ships no key. `dexterm voice uninstall` removes the runtime and keeps the downloaded voice model (add `--purge-model` to delete that too); the fallback `say` voice takes over again. Off macOS, install the prebuilt Piper binary and run `dexterm voice download piper-voice`.
30
+
31
+ ```sh
32
+ $ dexterm voice setup # macOS: private runtime + checksum-verified voice (asks first)
33
+ $ dexterm voice status # which engines and models this machine has
34
+ $ dexterm voice uninstall # remove the runtime (add --purge-model to drop the voice too)
35
+ ```
36
+
37
+ Once Piper is installed it is used automatically — no config change. The model is kept pre-warmed while voice is on, so the first word of a reply starts in about a fifth of a second. `voice.rate` still maps to its speaking speed; a `voice.pitch` setting does not apply to Piper (its pitch is fixed by the model) and is ignored.
38
+
39
+ **The fallback chain.** dexterm picks the first engine that can speak on this machine, and never a novelty voice or the machine's own system voice:
40
+
41
+ | platform | 1st | 2nd | then |
42
+ | --- | --- | --- | --- |
43
+ | macOS | Piper `en_GB-alan-medium` (after `dexterm voice setup`) | `say` with a deep British male voice (Eddy, then Daniel, then the next installed one on that list) | text only: the analyst still answers on screen |
44
+ | Linux (beta) | Piper (prebuilt binary + `dexterm voice download piper-voice`) | `espeak-ng` with a British male voice | text only |
45
+
46
+ Set `DEXTERM_VOICE_TTS` to `piper`, `say`, `espeak` or `none` to pin one engine. An explicit `say` never switches to Piper.
47
+
48
+ **Speed and delivery.** `<` slows the spoken reply and `>` speeds it up, 15 words a minute per press between 120 and 320 (the default is 205). The new rate is saved to `voice.rate` in `config.json`. Numbers are read the way a trader says them: a sub-cent price is spoken as the coin's market cap when the line includes one, and otherwise as "a tiny price". Years and SOL amounts are read as written. On the screener, "this one", "this coin" or "it" means the highlighted row.
@@ -0,0 +1,27 @@
1
+ ---
2
+ id: docs-voice-what-it-can-never-do
3
+ title: Jarvis voice mode › What it can never do
4
+ kind: docs
5
+ page: voice
6
+ page_title: Jarvis voice mode
7
+ heading: What it can never do
8
+ anchor: what-it-can-never-do
9
+ url: https://dexterm.xyz/docs/voice#what-it-can-never-do
10
+ tags:
11
+ - docs
12
+ - voice
13
+ - can
14
+ - never
15
+ - jarvis
16
+ - mode
17
+ confidence: high
18
+ owner: maintainers
19
+ origin: docs-generated
20
+ reviewed_by: generated@2026-10-16
21
+ generated_from: dexterm/site content/docs (task-1420)
22
+ sources:
23
+ - site/content/docs/voice.md
24
+ date: 2026-10-16
25
+ ---
26
+
27
+ Voice creates proposals only. The ticket it opens is PAPER, in its editing phase, and the keypress gate stands: your `⏎` then `y` (plus the typed-back size above the threshold) is the only way to a fill. Spoken "confirm", "send it", "y", "sign it", "go live", "arm it", "raise my cap", "panic" and "/wallet …" are routed as questions or ignored; they cannot flip the ticket to LIVE, arm a plan, touch the signer's caps, run a wallet command or press anything. The router's output is a closed set of decision kinds, a guard rejects any decision that carries a mode, live, arm, caps, confirm, sign or send field, and an in-app test drives the real key loop with the executor, the confirm paths, the LIVE flip and the wallet commands booby-trapped: twenty-one hostile utterances, zero touches.
@@ -0,0 +1,38 @@
1
+ ---
2
+ id: docs-voice-what-you-can-say
3
+ title: Jarvis voice mode › What you can say
4
+ kind: docs
5
+ page: voice
6
+ page_title: Jarvis voice mode
7
+ heading: What you can say
8
+ anchor: what-you-can-say
9
+ url: https://dexterm.xyz/docs/voice#what-you-can-say
10
+ tags:
11
+ - docs
12
+ - voice
13
+ - can
14
+ - say
15
+ - jarvis
16
+ - mode
17
+ confidence: high
18
+ owner: maintainers
19
+ origin: docs-generated
20
+ reviewed_by: generated@2026-10-16
21
+ generated_from: dexterm/site content/docs (task-1420)
22
+ sources:
23
+ - site/content/docs/voice.md
24
+ date: 2026-10-16
25
+ ---
26
+
27
+ | you say | what happens | path |
28
+ |---|---|---|
29
+ | "show me the runners", "go to new pairs", "open my watchlist", "positions" | switches the screen | instant, no model |
30
+ | "open bonk", "pull up wif" | opens that coin's token screen | instant |
31
+ | "filter liquidity over 50k", "only show age under 10 minutes" | sets the screener filter | instant |
32
+ | "watch this one", "add bonk to my watchlist" | adds to the watchlist | instant |
33
+ | "show the chart", "close the chart" | opens or closes the chart popup for the open coin through the popup host | instant |
34
+ | "buy bonk", "sell half of wif", "ape into this one" | opens a **PAPER ticket in its editing phase** for the spoken coin and says so | instant |
35
+ | "is this a rug?", "what do you think about wif", "tell me about the holders" | asks the analyst; the first two sentences of the answer are read aloud | Claude |
36
+ | "buy this if it dips to 300k, sell half at 600k, and leave a moon bag", "buy bonk if it drops to 250k, stop at 150k" | drafts an **order-plan proposal** (entry trigger, take-profit ladder, moon bag, stop) for the named or highlighted coin; it is inert until you arm it with a held keypress on the `O` screen or `dexterm plan arm` | instant, no model |
37
+
38
+ `m` mutes the replies, `,` cycles the macOS `say` voice (the fallback; Piper itself has one fixed voice), `<` / `>` make it slower or faster, `esc` stops a reply or cancels the mic. Only the keyboard changes the voice: the analyst can explain these keys but has no action that sets them. Any other key pressed while the mic is live closes it first and then does its normal job, and the mic auto-closes after 15 s if you walk away. On the ticket screen the voice keys are off, so nothing spoken can reach the confirm gate.
@@ -0,0 +1,25 @@
1
+ ---
2
+ id: docs-voice
3
+ title: Jarvis voice mode
4
+ kind: docs
5
+ page: voice
6
+ page_title: Jarvis voice mode
7
+ url: https://dexterm.xyz/docs/voice
8
+ tags:
9
+ - docs
10
+ - voice
11
+ - jarvis
12
+ - mode
13
+ confidence: high
14
+ owner: maintainers
15
+ origin: docs-generated
16
+ reviewed_by: generated@2026-10-16
17
+ generated_from: dexterm/site content/docs (task-1420)
18
+ sources:
19
+ - site/content/docs/voice.md
20
+ date: 2026-10-16
21
+ ---
22
+
23
+ Push-to-talk on v, an instant local command path, Claude for analysis, spoken replies, popups. Voice only ever proposes; it can never confirm, sign, flip LIVE or raise a cap.
24
+
25
+ `v` is push-to-talk. Press it once and the mic opens (a red `● LISTENING` badge sits on the band under the header the whole time it is live); say what you want; press `v` again to send. The first press enables voice for the run and asks macOS for Microphone and Speech permission. Everything is free and local: speech-out is the neural Piper voice once it is set up (otherwise the built-in `say`), speech-in is on-device Apple Speech (compiled once with `swiftc`) or a local whisper.cpp `base.en` model, and the only model in the loop is your own `claude` login, for analysis questions. No paid speech API exists in the code, no key is read, nothing is recorded to disk.
@@ -0,0 +1,258 @@
1
+ // @dexterm/mcp — the app-help knowledge base (task-1413).
2
+ //
3
+ // A SECOND bundled KB set, separate from the 17 memecoin-risk entries, that teaches an agent how dexterm
4
+ // ITSELF works: what each screen shows, the exact key for a task, the CLI subcommand/flag, and the MCP
5
+ // tools. The entries in `assets/kb/app-help/*.md` are GENERATED from the app's own keymap / help overlay /
6
+ // MCP tool list / CLI by `packages/cli/src/app-help-gen.ts` (committed, run in tests), so they cannot drift
7
+ // from the real app. This module only LOADS and SEARCHES them — it is read-only and dependency-free.
8
+ //
9
+ // It is kept out of the main KB store on purpose: the memecoin KB's "exactly 17 bundled entries" invariant
10
+ // stays true, and a "how do I …" search hits app-help first without the two sets diluting each other.
11
+ import path from 'node:path';
12
+ import { fileURLToPath } from 'node:url';
13
+ import { loadBundled } from "./user-content.js";
14
+ const HERE = path.dirname(fileURLToPath(import.meta.url));
15
+ /** The shipped app-help KB directory (read-only; generated). */
16
+ export const APP_HELP_DIR = path.resolve(HERE, '..', 'assets', 'kb', 'app-help');
17
+ function list(v) {
18
+ return Array.isArray(v) ? v.map(String) : typeof v === 'string' && v ? [v] : [];
19
+ }
20
+ function toAppHelp(e) {
21
+ return {
22
+ id: e.id,
23
+ title: String(e.meta.title ?? e.id),
24
+ screen: String(e.meta.screen ?? 'all'),
25
+ tags: list(e.meta.tags),
26
+ keys: list(e.meta.keys),
27
+ actions: list(e.meta.actions),
28
+ commands: list(e.meta.commands),
29
+ flags: list(e.meta.flags),
30
+ tools: list(e.meta.tools),
31
+ feature: String(e.meta.feature ?? ''),
32
+ body: e.body,
33
+ bytes: e.bytes,
34
+ };
35
+ }
36
+ /** Load every app-help entry (bundled-only; deterministic order by id). */
37
+ export function loadAppHelp(dir = APP_HELP_DIR) {
38
+ const entries = loadBundled([{ dir, layout: 'flat' }]).map(toAppHelp);
39
+ entries.sort((a, b) => a.id.localeCompare(b.id));
40
+ return entries;
41
+ }
42
+ // Generic words that carry no retrieval signal in a "how do I …" question — dropped before scoring so a
43
+ // short noise word ('to', 'my') can't substring-match an unrelated entry and outrank the real one.
44
+ const STOP = new Set([
45
+ 'how', 'do', 'does', 'did', 'the', 'a', 'an', 'to', 'my', 'me', 'i', 'is', 'it', 'its', 'of', 'in', 'on',
46
+ 'at', 'by', 'or', 'and', 'for', 'with', 'this', 'that', 'these', 'those', 'your', 'you', 'can', 'what',
47
+ 'which', 'where', 'when', 'who', 'am', 'are', 'be', 'get', 'got', 'use', 'using', 'make', 'want', 'need',
48
+ 'from', 'into', 'show', 'see', 'tell', 'about', 'some', 'any', 'all', 'up', 'out', 'off', 'on',
49
+ // generic action verbs — they appear in many entry titles ("Change…", "Switch…") and carry no signal.
50
+ 'change', 'switch', 'set', 'setting', 'turn', 'open', 'close', 'enable', 'disable', 'add', 'remove',
51
+ 'start', 'stop', 'run', 'cycle', 'pick', 'choose', 'save', 'view', 'check',
52
+ ]);
53
+ function tokenise(s) {
54
+ return (s.toLowerCase().match(/[a-z0-9][a-z0-9-]+/g) ?? []).filter((t) => !STOP.has(t));
55
+ }
56
+ /** A short, deterministic how-to synonym map so natural phrasings land on the right entry. */
57
+ const QUERY_SYNONYMS = {
58
+ paste: 'open', ca: 'open', 'contract-address': 'open', address: 'open', link: 'open',
59
+ screenshot: 'export', save: 'export', png: 'export', report: 'export', share: 'export',
60
+ speed: 'rate', faster: 'rate', slower: 'rate', wpm: 'rate',
61
+ speak: 'voice', talk: 'voice', jarvis: 'voice', mic: 'voice', microphone: 'voice',
62
+ notify: 'alert', notification: 'alerts', telegram: 'alerts', discord: 'alerts',
63
+ filtering: 'filter', query: 'filter',
64
+ marketcap: 'mcap', 'market-cap': 'mcap', cap: 'mcap',
65
+ honeypot: 'rug', safe: 'rug', scam: 'rug',
66
+ fake: 'larp', legit: 'larp', real: 'larp', website: 'larp', 'rug-pull': 'rug',
67
+ agent: 'mcp', agents: 'mcp', bot: 'mcp', claude: 'analyst',
68
+ helius: 'key', rpc: 'key', holders: 'key',
69
+ layout: 'workspace', workspaces: 'workspace',
70
+ keybind: 'keymap', keybinding: 'keymap', rebind: 'keymap', shortcut: 'keymap',
71
+ theme: 'theme', colour: 'theme', color: 'theme',
72
+ buy: 'paper', sell: 'paper', trade: 'paper', ticket: 'paper',
73
+ upgrade: 'update',
74
+ chart: 'popup', candles: 'popup',
75
+ bubbles: 'bubble', cluster: 'bubble', clusters: 'bubble',
76
+ scanner: 'scan', watcher: 'scan',
77
+ copy: 'follow', mirror: 'follow', unfollow: 'follow',
78
+ };
79
+ function expand(terms) {
80
+ const out = new Set(terms);
81
+ for (const t of terms) {
82
+ const s = QUERY_SYNONYMS[t];
83
+ if (s)
84
+ out.add(s);
85
+ }
86
+ return [...out];
87
+ }
88
+ /** Raw word tokens of a haystack (no stopword filtering), for exact word-boundary matching. */
89
+ function words(s) {
90
+ return s.toLowerCase().match(/[a-z0-9][a-z0-9-]+/g) ?? [];
91
+ }
92
+ /**
93
+ * Deterministic keyword retrieval over the app-help set (no model). Matches on WORD BOUNDARIES (not
94
+ * substrings) so "screener" does not match the tag "dexscreener" and "token" does not match a tool name
95
+ * like "open_token". title/tags/screen/feature score strongest; the body is the weak tail.
96
+ */
97
+ export function searchAppHelp(query, limit = 5, entries = loadAppHelp()) {
98
+ const terms = expand(tokenise(query));
99
+ // A query whose only meaningful word is a screen name ("what does the screener show") is a request for
100
+ // that screen's overview, not for a topic that happens to run there.
101
+ const soleScreen = terms.length === 1 ? terms[0] : null;
102
+ // An explicit "... screen ..." question ("what does the kol screen show") is a request for that screen's
103
+ // overview even when other words survive; boost the matching overview so it beats a topic that shares the name.
104
+ const asksScreen = words(query).includes('screen');
105
+ const scored = entries.map((e) => {
106
+ const overview = e.id.startsWith('screen-');
107
+ // Screen field matches only for an overview entry; on a topic it is just where the action happens.
108
+ const strong = new Set(words(`${e.title} ${e.tags.join(' ')} ${e.feature}${overview ? ' ' + e.screen : ''}`));
109
+ // An overview's body is the enumerated key list — it names every action word, so it is NOT scored
110
+ // (else "sort the screener" would match the screener overview's `s — sort` line over the sort topic).
111
+ const bodyWords = overview ? [] : words(e.body);
112
+ let score = 0;
113
+ for (const t of terms) {
114
+ if (strong.has(t))
115
+ score += 4;
116
+ let n = 0;
117
+ for (const w of bodyWords)
118
+ if (w === t)
119
+ n++;
120
+ score += Math.min(n, 3);
121
+ }
122
+ if (overview && soleScreen && soleScreen === e.screen)
123
+ score += 6;
124
+ if (overview && asksScreen && terms.includes(e.screen))
125
+ score += 3;
126
+ return { e, score };
127
+ }).filter((x) => x.score > 0)
128
+ .sort((a, b) => (b.score - a.score) || a.e.id.localeCompare(b.e.id))
129
+ .slice(0, limit);
130
+ return scored.map(({ e, score }) => ({ ...e, score }));
131
+ }
132
+ /** Fetch one app-help entry by id. */
133
+ export function getAppHelp(id, entries = loadAppHelp()) {
134
+ return entries.find((e) => e.id === id) ?? null;
135
+ }
136
+ // ---------------------------------------------------------------------------------------- docs (task-1420)
137
+ // A THIRD bundled set: every page of the site docs (dexterm.xyz/docs), chunked by heading. GENERATED from the
138
+ // site by `packages/cli/src/docs-kb-gen.ts` (committed; a regenerate-and-diff test runs when the site checkout
139
+ // is present). The app-help entries stay the authority for an exact key or command; a docs entry carries the
140
+ // explanation and the URL to cite, and NEVER structured keys/commands/flags/tools. Its text is reference DATA:
141
+ // the app_help tool hands it to a model firewalled (`<untrusted kind="docs">`), so an instruction written into
142
+ // a docs page reads as quoted text, never as an order.
143
+ /** The shipped docs KB directory (read-only; generated from the site docs). */
144
+ export const DOCS_KB_DIR = path.resolve(HERE, '..', 'assets', 'kb', 'docs');
145
+ function toDocs(e) {
146
+ return {
147
+ id: e.id,
148
+ title: String(e.meta.title ?? e.id),
149
+ page: String(e.meta.page ?? ''),
150
+ pageTitle: String(e.meta.page_title ?? ''),
151
+ heading: String(e.meta.heading ?? ''),
152
+ anchor: String(e.meta.anchor ?? ''),
153
+ url: String(e.meta.url ?? ''),
154
+ tags: list(e.meta.tags),
155
+ body: e.body,
156
+ bytes: e.bytes,
157
+ };
158
+ }
159
+ /** Load every docs entry (bundled-only; deterministic order by id). */
160
+ export function loadDocsKb(dir = DOCS_KB_DIR) {
161
+ const entries = loadBundled([{ dir, layout: 'flat' }]).map(toDocs);
162
+ entries.sort((a, b) => a.id.localeCompare(b.id));
163
+ return entries;
164
+ }
165
+ /**
166
+ * A light, deterministic stemmer for the docs set only (prose, unlike the app-help titles): "answers"/"answer",
167
+ * "cached"/"cache", "clarifies"/"clarify", "streaming"/"stream" meet. Short words are left alone.
168
+ */
169
+ function stem(w) {
170
+ if (w.length < 4 || w.includes('-'))
171
+ return w;
172
+ let s = w;
173
+ if (s.endsWith('ies') && s.length > 4)
174
+ s = s.slice(0, -3) + 'y';
175
+ else if (s.endsWith('ing') && s.length > 5)
176
+ s = s.slice(0, -3);
177
+ else if (s.endsWith('ed') && s.length > 4)
178
+ s = s.slice(0, -2);
179
+ else if (/(?:ss|sh|ch|x|z)es$/.test(s))
180
+ s = s.slice(0, -2);
181
+ else if (s.endsWith('s') && !s.endsWith('ss'))
182
+ s = s.slice(0, -1);
183
+ if (s.endsWith('e') && s.length > 3)
184
+ s = s.slice(0, -1);
185
+ return s;
186
+ }
187
+ /**
188
+ * Deterministic keyword retrieval over the docs set (no model), same word-boundary matching as app-help.
189
+ * The section heading and tags score strongest, the page title less (every section of a page shares it),
190
+ * the body is the weak tail.
191
+ */
192
+ export function searchDocs(query, limit = 5, entries = loadDocsKb()) {
193
+ const terms = [...new Set(expand(tokenise(query)).map(stem))];
194
+ const scored = entries.map((e) => {
195
+ const strong = new Set(words(`${e.heading} ${e.tags.filter((t) => t !== 'docs').join(' ')}`).map(stem));
196
+ const page = new Set(words(`${e.pageTitle} ${e.page}`).map(stem));
197
+ const bodyWords = words(e.body).map(stem);
198
+ let score = 0;
199
+ for (const t of terms) {
200
+ if (strong.has(t))
201
+ score += 4;
202
+ else if (page.has(t))
203
+ score += 2;
204
+ let n = 0;
205
+ for (const w of bodyWords)
206
+ if (w === t)
207
+ n++;
208
+ score += Math.min(n, 3);
209
+ }
210
+ // A question that names a section's own heading words is about that section: +3 per heading word
211
+ // matched (+2 more when it names all of them), so "what is redacted in the spectator view" lands on "What is redacted",
212
+ // not on the page's other sections that merely share the page title.
213
+ const head = new Set(tokenise(e.heading).map(stem));
214
+ let hit = 0;
215
+ for (const w of head)
216
+ if (terms.includes(w))
217
+ hit++;
218
+ if (hit >= 1 && head.size > 0)
219
+ score += 3 * hit + (hit === head.size ? 2 : 0);
220
+ return { e, score };
221
+ }).filter((x) => x.score > 0)
222
+ .sort((a, b) => (b.score - a.score) || a.e.id.localeCompare(b.e.id))
223
+ .slice(0, limit);
224
+ return scored.map(({ e, score }) => ({ ...e, score }));
225
+ }
226
+ /** Fetch one docs entry by id. */
227
+ export function getDocs(id, entries = loadDocsKb()) {
228
+ return entries.find((e) => e.id === id) ?? null;
229
+ }
230
+ /** Words that make a question about an exact key or command: app-help answers it. */
231
+ const KEY_OR_COMMAND = /\b(?:key|keys|keybind\w*|press|pressing|shortcut|shortcuts|hotkey|hotkeys|command|commands|subcommand|subcommands|flag|flags|cli)\b/i;
232
+ /** "how do I …" / "how to …": a how-to, answered by an app-help topic. */
233
+ const HOW_TO = /^\s*how\s+(?:do|can|could|would|should)\s+(?:i|you|we)\b|^\s*how\s+to\b/i;
234
+ /** A conceptual question opens with a question word ("what is …", "does it …", "how does …", "how long …"). */
235
+ const CONCEPT = /^\s*(?:what|whats|what's|why|is|are|does|do|did|can|could|will|would|should|where|when|which|who|how)\b/i;
236
+ /** About a screen ("what does the token screen show") or the coin on it ("is this coin a rug"): an app-help topic/tool. */
237
+ const APP_SUBJECT = /\b(?:screen|screener)\b|\bthis\s+(?:[a-z-]+\s+){0,2}(?:coin|token|project)\b/i;
238
+ /** The question's shape: 'key' (exact key/command, a how-to, an imperative, a screen/this-coin question) or 'concept'. */
239
+ export function helpIntent(query) {
240
+ if (KEY_OR_COMMAND.test(query) || HOW_TO.test(query) || APP_SUBJECT.test(query))
241
+ return 'key';
242
+ return CONCEPT.test(query) ? 'concept' : 'key';
243
+ }
244
+ /**
245
+ * The analyst's help search (task-1420): app-help AND the docs, merged by the question's shape.
246
+ * - a key/command question, a how-to or an imperative ("export the view", "how do I sort"): app-help ranks
247
+ * first (it carries the exact key/command), the docs after it;
248
+ * - a conceptual question ("what is redacted in the spectator view", "does voice work on linux"): the docs rank
249
+ * first (nothing ranks above them), the app-help after.
250
+ * Either way the answer keeps both sets in view: up to 3 hits of the leading set, then up to 2 of the other,
251
+ * then the rest. A set with no hits simply yields to the other (a docs-only answer beats no answer).
252
+ */
253
+ export function searchHelp(query, limit = 5, sets = {}) {
254
+ const app = searchAppHelp(query, limit, sets.appHelp ?? loadAppHelp()).map((e) => ({ ...e, origin: 'app-help' }));
255
+ const docs = searchDocs(query, limit, sets.docs ?? loadDocsKb()).map((e) => ({ ...e, origin: 'docs' }));
256
+ const [lead, other] = helpIntent(query) === 'concept' ? [docs, app] : [app, docs];
257
+ return [...lead.slice(0, 3), ...other.slice(0, 2), ...lead.slice(3), ...other.slice(2)].slice(0, limit);
258
+ }
@@ -1,7 +1,7 @@
1
1
  // Prompt firewall (CL-06), spec'd in SPEC §5.3. Kept tiny and total. Every untrusted string — token text,
2
2
  // web pages, RugCheck risks, and (task-1377) user- or pack-edited KB entries and skills — passes through
3
- // here before a model sees it.
4
- export const LIMITS = { name: 64, symbol: 16, description: 512, risk: 160, kb: 4000, page: 1600, link: 40, skill: 8000 };
3
+ // here before a model sees it. (task-1420) The generated docs KB sections pass through as kind `docs`.
4
+ export const LIMITS = { name: 64, symbol: 16, description: 512, risk: 160, kb: 4000, page: 1600, link: 40, skill: 8000, docs: 6000 };
5
5
  export function firewall(text, source, kind = 'description', opts = {}) {
6
6
  if (text === null || text === undefined)
7
7
  return null;
@@ -1,9 +1,13 @@
1
1
  // @dexterm/mcp — read-only MCP server over stdio (SPEC §5, D-09 / task-1302).
2
2
  // Every tool is read-only and schema-described; nothing in this package may build,
3
3
  // sign or send a transaction (SPEC §5.2, §6.3).
4
- export { runStdioServer, selfTest, McpTools, TOOLS, READ_ONLY_TOOLS, firewall, listPrompts, getPrompt, resourceList, resourceRead, overlayCounts, userSkillPreamble, BUNDLED_KB_DIR, BUNDLED_SKILLS_DIR } from "./server.js";
4
+ export { runStdioServer, selfTest, McpTools, TOOLS, READ_ONLY_TOOLS, appHelpAnswer, firewall, listPrompts, getPrompt, resourceList, resourceRead, overlayCounts, userSkillPreamble, BUNDLED_KB_DIR, BUNDLED_SKILLS_DIR } from "./server.js";
5
5
  export { OverlayStore, mergeOverlay, loadBundled, checkKb, checkSkill, moneyToolMentions, isMoneyToolName, parseFrontmatter, dextermHome, userKbDir, userSkillsDir, userDir, contentJournalPath, journalContent, writeOverlayFile, resetOverlayFile, templateFor, KB_LIMITS, SKILL_LIMITS, KB_ID, SKILL_NAME, KB_RULE, MONEY_TOOLS, } from "./user-content.js";
6
6
  export { buildDossier } from "./dossier.js";
7
+ // task-1406 + task-1421: the spectator sink the tool-call path writes to when a spectator surface is open
8
+ // (via DEXTERM_SPECTATOR_FILE, or the ~/.dexterm rendezvous an external `dexterm mcp` client uses).
9
+ export { recordForToolCall, maxAgeSec, fileSpectatorSinkFromEnv, resolveSpectatorSink, rendezvousPath, MCP_SPECTATOR_RENDEZVOUS, } from "./spectator-sink.js";
10
+ export { loadAppHelp, searchAppHelp, getAppHelp, APP_HELP_DIR, loadDocsKb, searchDocs, getDocs, searchHelp, DOCS_KB_DIR, helpIntent } from "./app-help.js";
7
11
  /** Tool names served in v1 (SPEC §5.2 core + the task-1293 KB/case tools + the task-1314 dossier). */
8
12
  export const PLANNED_TOOLS = [
9
13
  'screen_state',