dexterm-cli 0.1.6 → 0.1.7
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.
- package/dist/packages/agents/src/schema.js +22 -1
- package/dist/packages/agents/src/story.js +11 -2
- package/dist/packages/agents/src/tiers.js +27 -2
- package/dist/packages/agents/src/tools.js +30 -2
- package/dist/packages/autotrade/assets/exit-profile.schema.json +492 -0
- package/dist/packages/autotrade/assets/profiles/moonbag.json +46 -0
- package/dist/packages/autotrade/assets/profiles/runner.json +88 -0
- package/dist/packages/autotrade/assets/profiles/scalp.json +88 -0
- package/dist/packages/autotrade/assets/profiles/swing.json +88 -0
- package/dist/packages/autotrade/assets/strategies/moonbag.json +101 -0
- package/dist/packages/autotrade/assets/strategies/runner.json +101 -0
- package/dist/packages/autotrade/assets/strategies/sample-dip-ladder.json +188 -0
- package/dist/packages/autotrade/assets/strategies/scalp.json +98 -0
- package/dist/packages/autotrade/assets/strategies/swing.json +97 -0
- package/dist/packages/autotrade/assets/strategies/yolo.json +157 -0
- package/dist/packages/autotrade/assets/tapes/yolo-rehearsal.json +1 -0
- package/dist/packages/autotrade/src/account.js +74 -0
- package/dist/packages/autotrade/src/backtest.js +357 -0
- package/dist/packages/autotrade/src/basis-text.js +32 -0
- package/dist/packages/autotrade/src/chat/approvals.js +484 -0
- package/dist/packages/autotrade/src/chat/audit.js +140 -0
- package/dist/packages/autotrade/src/chat/config.js +93 -0
- package/dist/packages/autotrade/src/chat/connector.js +24 -0
- package/dist/packages/autotrade/src/chat/control.js +103 -0
- package/dist/packages/autotrade/src/chat/fake.js +100 -0
- package/dist/packages/autotrade/src/chat/format.js +71 -0
- package/dist/packages/autotrade/src/chat/hub.js +187 -0
- package/dist/packages/autotrade/src/chat/index.js +18 -0
- package/dist/packages/autotrade/src/chat/notify.js +292 -0
- package/dist/packages/autotrade/src/chat/pairing.js +46 -0
- package/dist/packages/autotrade/src/chat/redact.js +48 -0
- package/dist/packages/autotrade/src/chat/secrets.js +99 -0
- package/dist/packages/autotrade/src/chat/service.js +248 -0
- package/dist/packages/autotrade/src/chat/telegram.js +290 -0
- package/dist/packages/autotrade/src/desk-executor.js +188 -0
- package/dist/packages/autotrade/src/engine.js +387 -0
- package/dist/packages/autotrade/src/execution-port.js +97 -0
- package/dist/packages/autotrade/src/fleet-config.js +169 -0
- package/dist/packages/autotrade/src/fleet-control.js +276 -0
- package/dist/packages/autotrade/src/fleet.js +639 -0
- package/dist/packages/autotrade/src/index.js +53 -0
- package/dist/packages/autotrade/src/ledger.js +108 -0
- package/dist/packages/autotrade/src/live-source.js +182 -0
- package/dist/packages/autotrade/src/monitor-daemon.js +715 -0
- package/dist/packages/autotrade/src/monitor.js +190 -0
- package/dist/packages/autotrade/src/ollama-sessions.js +137 -0
- package/dist/packages/autotrade/src/paper-accounts.js +72 -0
- package/dist/packages/autotrade/src/replay.js +198 -0
- package/dist/packages/autotrade/src/runner-config.js +99 -0
- package/dist/packages/autotrade/src/runner.js +872 -0
- package/dist/packages/autotrade/src/safety.js +243 -0
- package/dist/packages/autotrade/src/session.js +269 -0
- package/dist/packages/autotrade/src/sessions.js +503 -0
- package/dist/packages/autotrade/src/store.js +250 -0
- package/dist/packages/autotrade/src/strategy.js +256 -0
- package/dist/packages/autotrade/src/trade-ledger.js +241 -0
- package/dist/packages/autotrade/src/yolo.js +140 -0
- package/dist/packages/cli/assets/claude/analyst-system.md +4 -4
- package/dist/packages/cli/assets/claude/plugin/skills/token-dossier/SKILL.md +1 -1
- package/dist/packages/cli/src/ai-cmd.js +412 -0
- package/dist/packages/cli/src/analyst/backend.js +82 -15
- package/dist/packages/cli/src/analyst/codex.js +14 -9
- package/dist/packages/cli/src/analyst/ollama.js +263 -0
- package/dist/packages/cli/src/analyst/session.js +5 -2
- package/dist/packages/cli/src/app-help-gen.js +44 -8
- package/dist/packages/cli/src/autotrade-cmd/audit.js +57 -0
- package/dist/packages/cli/src/autotrade-cmd/backtest.js +199 -0
- package/dist/packages/cli/src/autotrade-cmd/flatten.js +64 -0
- package/dist/packages/cli/src/autotrade-cmd/fleet.js +397 -0
- package/dist/packages/cli/src/autotrade-cmd/requests.js +79 -0
- package/dist/packages/cli/src/autotrade-cmd/run.js +413 -0
- package/dist/packages/cli/src/autotrade-cmd/stop.js +76 -0
- package/dist/packages/cli/src/autotrade-cmd/strategies.js +198 -0
- package/dist/packages/cli/src/autotrade-cmd/strategy-control.js +174 -0
- package/dist/packages/cli/src/autotrade-cmd/telegram-host.js +101 -0
- package/dist/packages/cli/src/autotrade-cmd.js +168 -0
- package/dist/packages/cli/src/display.js +156 -17
- package/dist/packages/cli/src/doctor.js +62 -3
- package/dist/packages/cli/src/export.js +10 -2
- package/dist/packages/cli/src/index.js +1 -1
- package/dist/packages/cli/src/ledger-cmd.js +288 -0
- package/dist/packages/cli/src/live/chart-fills.js +46 -0
- package/dist/packages/cli/src/live/index.js +23 -89
- package/dist/packages/cli/src/live/screens/token-live.js +9 -6
- package/dist/packages/cli/src/live/trade.js +12 -457
- package/dist/packages/cli/src/live/watchlist.js +1 -1
- package/dist/packages/cli/src/main.js +147 -190
- package/dist/packages/cli/src/mcp-cmd.js +7 -1
- package/dist/packages/cli/src/plan-cmd.js +1 -1
- package/dist/packages/cli/src/pnl-app.js +31 -21
- package/dist/packages/cli/src/pnl-card.js +158 -21
- package/dist/packages/cli/src/popup.js +22 -6
- package/dist/packages/cli/src/record-cmd.js +141 -20
- package/dist/packages/cli/src/screens/agent-hud.js +34 -2
- package/dist/packages/cli/src/screens/analyst-session.js +7 -4
- package/dist/packages/cli/src/screens/analyst.js +3 -2
- package/dist/packages/cli/src/screens/autotrade-keys.js +169 -0
- package/dist/packages/cli/src/screens/autotrade-proposals.js +123 -0
- package/dist/packages/cli/src/screens/autotrade-screen.js +725 -0
- package/dist/packages/cli/src/screens/autotrade-ui.js +640 -0
- package/dist/packages/cli/src/screens/autotrade-worker.js +89 -0
- package/dist/packages/cli/src/screens/brain.js +37 -11
- package/dist/packages/cli/src/screens/overlay.js +5 -2
- package/dist/packages/cli/src/screens/plans.js +5 -17
- package/dist/packages/cli/src/screens/pnl-chip.js +9 -8
- package/dist/packages/cli/src/screens/positions.js +6 -28
- package/dist/packages/cli/src/screens/ticket.js +38 -205
- package/dist/packages/cli/src/screens/token.js +3 -3
- package/dist/packages/cli/src/state.js +25 -19
- package/dist/packages/cli/src/telegram-cmd.js +451 -0
- package/dist/packages/cli/src/trade.js +3 -128
- package/dist/packages/cli/src/version.js +1 -1
- package/dist/packages/cli/src/wallet-cmd.js +39 -340
- package/dist/packages/cli/src/wallet-command.js +8 -11
- package/dist/packages/cli/src/widgets.js +0 -12
- package/dist/packages/custom/src/config.js +20 -2
- package/dist/packages/custom/src/schema.js +35 -10
- package/dist/packages/custom/src/workspace.js +3 -3
- package/dist/packages/data/src/basis.js +191 -0
- package/dist/packages/data/src/detail.js +53 -2
- package/dist/packages/data/src/index.js +0 -14
- package/dist/packages/data/src/store.js +14 -5
- package/dist/packages/data/src/trade/agent/paper-desk.js +228 -16
- package/dist/packages/data/src/trade/agent/rendezvous.js +3 -2
- package/dist/packages/data/src/trade/bridge.js +4 -102
- package/dist/packages/data/src/trade/ledger/export.js +101 -0
- package/dist/packages/data/src/trade/ledger/file.js +135 -0
- package/dist/packages/data/src/trade/ledger/fold.js +191 -0
- package/dist/packages/data/src/trade/ledger/index.js +9 -0
- package/dist/packages/data/src/trade/ledger/schema.js +83 -0
- package/dist/packages/data/src/trade/ledger/sources.js +307 -0
- package/dist/packages/data/src/trade/ledger/stats.js +123 -0
- package/dist/packages/data/src/trade/ledger/tags.js +116 -0
- package/dist/packages/data/src/trade/ledger/view.js +51 -0
- package/dist/packages/data/src/trade/plans/index.js +0 -1
- package/dist/packages/data/src/trade/plans/service.js +3 -27
- package/dist/packages/mcp/assets/kb/app-help/autotrade-chat.md +48 -0
- package/dist/packages/mcp/assets/kb/app-help/autotrade-parallel.md +42 -0
- package/dist/packages/mcp/assets/kb/app-help/autotrade-runner.md +35 -0
- package/dist/packages/mcp/assets/kb/app-help/autotrade-stop.md +37 -0
- package/dist/packages/mcp/assets/kb/app-help/autotrade-strategies.md +35 -0
- package/dist/packages/mcp/assets/kb/app-help/autotrade-telegram.md +40 -0
- package/dist/packages/mcp/assets/kb/app-help/chart-trade-markers.md +42 -0
- package/dist/packages/mcp/assets/kb/app-help/link-a-wallet.md +4 -10
- package/dist/packages/mcp/assets/kb/app-help/live-trading.md +38 -0
- package/dist/packages/mcp/assets/kb/app-help/live-yolo.md +34 -0
- package/dist/packages/mcp/assets/kb/app-help/order-plans.md +1 -1
- package/dist/packages/mcp/assets/kb/app-help/price-or-marketcap.md +5 -2
- package/dist/packages/mcp/assets/kb/app-help/screen-analyst.md +3 -0
- package/dist/packages/mcp/assets/kb/app-help/screen-autotrade.md +217 -0
- package/dist/packages/mcp/assets/kb/app-help/screen-kol.md +3 -0
- package/dist/packages/mcp/assets/kb/app-help/screen-newpairs.md +3 -0
- package/dist/packages/mcp/assets/kb/app-help/screen-positions.md +3 -0
- package/dist/packages/mcp/assets/kb/app-help/screen-screener.md +3 -0
- package/dist/packages/mcp/assets/kb/app-help/screen-token.md +3 -0
- package/dist/packages/mcp/assets/kb/app-help/screen-trending.md +3 -0
- package/dist/packages/mcp/assets/kb/app-help/screen-watchlist.md +3 -0
- package/dist/packages/mcp/assets/kb/app-help/standing-mandates.md +1 -1
- package/dist/packages/mcp/assets/kb/app-help/trade-ledger.md +54 -0
- package/dist/packages/mcp/assets/kb/app-help/use-local-model.md +38 -0
- package/dist/packages/mcp/assets/kb/docs/docs-agents-agent-paper-trading.md +4 -1
- package/dist/packages/mcp/assets/kb/docs/docs-agents-reading-your-trade-ledger.md +31 -0
- package/dist/packages/mcp/assets/kb/docs/docs-agents-untrusted-by-default.md +1 -1
- package/dist/packages/mcp/assets/kb/docs/docs-analyst-if-claude-is-missing.md +1 -1
- package/dist/packages/mcp/assets/kb/docs/docs-analyst-use-a-local-model-instead.md +27 -0
- package/dist/packages/mcp/assets/kb/docs/docs-analyst-what-it-sees.md +2 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade-backtests-and-their-limits.md +56 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade-change-a-strategy-by-chat.md +49 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade-checking-the-record-of-a-run.md +28 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade-comparing-them.md +41 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade-exits-and-wakes.md +76 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade-how-a-stop-reaches-the-runner.md +32 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade-on-the-q-screen.md +37 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade-one-strategy-or-all-of-them.md +35 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade-paper-accounts.md +50 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade-presets.md +37 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade-running-it-all-day.md +31 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade-sessions-and-their-limits.md +31 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade-several-strategies-at-once.md +33 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade-stopping-it.md +35 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade-strategies-and-presets.md +34 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade-the-autotrade-json-file.md +48 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade-the-heartbeat.md +27 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade-the-run-file-and-the-heartbeat.md +34 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade-the-runner-and-candidate-sessions.md +45 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade-what-each-session-shows-first.md +31 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade-what-it-costs-claude-usage-per-session.md +58 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade-what-it-is-paper-self-directed.md +43 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade-what-it-will-not-do.md +31 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade-which-account-day-caps-and-the-usage-guard.md +44 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade-your-strategies.md +37 -0
- package/dist/packages/mcp/assets/kb/docs/docs-autotrade.md +22 -0
- package/dist/packages/mcp/assets/kb/docs/docs-beginners-before-any-experimental-trading.md +2 -2
- package/dist/packages/mcp/assets/kb/docs/docs-beginners.md +1 -1
- package/dist/packages/mcp/assets/kb/docs/docs-configuration-chart-markers.md +30 -0
- package/dist/packages/mcp/assets/kb/docs/docs-configuration-chart-y-axis.md +1 -1
- package/dist/packages/mcp/assets/kb/docs/docs-configuration-environment-variables.md +4 -1
- package/dist/packages/mcp/assets/kb/docs/docs-configuration-files-on-disk.md +1 -0
- package/dist/packages/mcp/assets/kb/docs/docs-configuration-headless-recorder-dexterm-record.md +3 -1
- package/dist/packages/mcp/assets/kb/docs/docs-configuration-price-display-mode.md +8 -6
- package/dist/packages/mcp/assets/kb/docs/docs-copy-trading-stage-2-the-one-key-mirror-ticket-a-proposal.md +1 -1
- package/dist/packages/mcp/assets/kb/docs/docs-copy-trading-stage-3-capped-auto-mirror-default-off-less.md +1 -1
- package/dist/packages/mcp/assets/kb/docs/docs-copy-trading-what-is-proven-what-is-not.md +1 -1
- package/dist/packages/mcp/assets/kb/docs/docs-copy-trading.md +1 -1
- package/dist/packages/mcp/assets/kb/docs/docs-data-sources-recorded-history-and-retention.md +36 -0
- package/dist/packages/mcp/assets/kb/docs/docs-data-sources-sources.md +1 -0
- package/dist/packages/mcp/assets/kb/docs/docs-getting-started-first-run.md +1 -1
- package/dist/packages/mcp/assets/kb/docs/docs-getting-started-install.md +3 -3
- package/dist/packages/mcp/assets/kb/docs/docs-getting-started-requirements.md +1 -1
- package/dist/packages/mcp/assets/kb/docs/docs-getting-started.md +1 -1
- package/dist/packages/mcp/assets/kb/docs/docs-live-trading-changed-in-0-1-7.md +26 -0
- package/dist/packages/mcp/assets/kb/docs/docs-live-trading-stopping.md +28 -0
- package/dist/packages/mcp/assets/kb/docs/docs-live-trading-the-short-version.md +34 -0
- package/dist/packages/mcp/assets/kb/docs/docs-live-trading-using-a-trading-bot-with-dexterm.md +33 -0
- package/dist/packages/mcp/assets/kb/docs/docs-live-trading-what-dexterm-does-not-do.md +30 -0
- package/dist/packages/mcp/assets/kb/docs/docs-live-trading-what-dexterm-does.md +29 -0
- package/dist/packages/mcp/assets/kb/docs/docs-live-trading.md +23 -0
- package/dist/packages/mcp/assets/kb/docs/docs-ollama-another-machine.md +28 -0
- package/dist/packages/mcp/assets/kb/docs/docs-ollama-autotrade-on-a-local-model.md +29 -0
- package/dist/packages/mcp/assets/kb/docs/docs-ollama-check-your-model-dexterm-ai-probe.md +38 -0
- package/dist/packages/mcp/assets/kb/docs/docs-ollama-how-we-checked.md +27 -0
- package/dist/packages/mcp/assets/kb/docs/docs-ollama-models-without-tool-calling.md +32 -0
- package/dist/packages/mcp/assets/kb/docs/docs-ollama-pick-the-engine-globally-or-per-surface.md +43 -0
- package/dist/packages/mcp/assets/kb/docs/docs-ollama-restriction-profiles.md +35 -0
- package/dist/packages/mcp/assets/kb/docs/docs-ollama-set-it-up-in-two-minutes.md +39 -0
- package/dist/packages/mcp/assets/kb/docs/docs-ollama-troubleshooting.md +35 -0
- package/dist/packages/mcp/assets/kb/docs/docs-ollama-what-runs-on-a-local-model.md +39 -0
- package/dist/packages/mcp/assets/kb/docs/docs-ollama-what-stays-outside-the-model.md +36 -0
- package/dist/packages/mcp/assets/kb/docs/docs-ollama-which-model.md +38 -0
- package/dist/packages/mcp/assets/kb/docs/docs-ollama-your-own-agent-on-the-local-model.md +28 -0
- package/dist/packages/mcp/assets/kb/docs/docs-ollama.md +28 -0
- package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-letting-an-agent-paper-trade-experimental.md +3 -4
- package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-link-a-wallet-read-only.md +30 -0
- package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-order-plans-and-standing-mandates.md +3 -4
- package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-panic.md +4 -7
- package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-paper-only-mandates.md +6 -7
- package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-pnl-cards.md +7 -7
- package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-the-safety-model.md +34 -0
- package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-the-ticket.md +3 -4
- package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-the-trade-ledger.md +42 -0
- package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-the-wallet.md +4 -5
- package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-trade-moments.md +4 -5
- package/dist/packages/mcp/assets/kb/docs/docs-paper-trading.md +4 -5
- package/dist/packages/mcp/assets/kb/docs/docs-popup-chart-buy-and-sell-markers.md +37 -0
- package/dist/packages/mcp/assets/kb/docs/docs-popup-chart-what-it-shows.md +2 -1
- package/dist/packages/mcp/assets/kb/docs/docs-screens-autotrade-paper.md +26 -0
- package/dist/packages/mcp/assets/kb/docs/docs-screens-order-plans.md +1 -1
- package/dist/packages/mcp/assets/kb/docs/docs-screens-token-screen.md +2 -0
- package/dist/packages/mcp/assets/kb/docs/docs-spectator-the-brain-view-and-the-pnl-chip.md +1 -1
- package/dist/packages/mcp/assets/kb/docs/docs-telegram-approve-one-tap-entries.md +50 -0
- package/dist/packages/mcp/assets/kb/docs/docs-telegram-control-the-commands.md +43 -0
- package/dist/packages/mcp/assets/kb/docs/docs-telegram-if-something-goes-wrong.md +30 -0
- package/dist/packages/mcp/assets/kb/docs/docs-telegram-notify-what-reaches-your-phone.md +41 -0
- package/dist/packages/mcp/assets/kb/docs/docs-telegram-set-it-up.md +47 -0
- package/dist/packages/mcp/assets/kb/docs/docs-telegram-the-record.md +26 -0
- package/dist/packages/mcp/assets/kb/docs/docs-telegram-what-it-is.md +33 -0
- package/dist/packages/mcp/assets/kb/docs/docs-telegram-what-it-will-not-do.md +31 -0
- package/dist/packages/mcp/assets/kb/docs/docs-telegram.md +23 -0
- package/dist/packages/mcp/assets/kb/docs/docs-troubleshooting-common-questions.md +1 -1
- package/dist/packages/mcp/assets/kb/docs/docs-troubleshooting-doctor-lines.md +4 -0
- package/dist/packages/mcp/assets/kb/docs/docs-voice-linux-and-windows.md +1 -1
- package/dist/packages/mcp/assets/kb/docs/docs-voice.md +1 -1
- package/dist/packages/mcp/assets/kb/docs/docs-yolo-1-replay-it-on-your-own-history.md +42 -0
- package/dist/packages/mcp/assets/kb/docs/docs-yolo-2-run-it-on-paper.md +34 -0
- package/dist/packages/mcp/assets/kb/docs/docs-yolo-3-watch-it-and-stop-it.md +32 -0
- package/dist/packages/mcp/assets/kb/docs/docs-yolo-the-rules.md +37 -0
- package/dist/packages/mcp/assets/kb/docs/docs-yolo-what-it-is.md +34 -0
- package/dist/packages/mcp/assets/kb/docs/docs-yolo-what-it-will-not-do.md +31 -0
- package/dist/packages/mcp/assets/kb/docs/docs-yolo.md +26 -0
- package/dist/packages/mcp/assets/kb/entries/autotrade.md +38 -0
- package/dist/packages/mcp/src/app-help.js +1 -1
- package/dist/packages/mcp/src/autotrade-tools.js +944 -0
- package/dist/packages/mcp/src/backtest-requests.js +71 -0
- package/dist/packages/mcp/src/engine/config.js +159 -0
- package/dist/packages/mcp/src/engine/index.js +10 -0
- package/dist/packages/mcp/src/engine/loop.js +101 -0
- package/dist/packages/mcp/src/engine/mcp-client.js +123 -0
- package/dist/packages/mcp/src/engine/ollama.js +258 -0
- package/dist/packages/mcp/src/engine/probe.js +110 -0
- package/dist/packages/mcp/src/engine/reason.js +35 -0
- package/dist/packages/mcp/src/engine/restrictions.js +111 -0
- package/dist/packages/mcp/src/index.js +7 -1
- package/dist/packages/mcp/src/ledger-tools.js +346 -0
- package/dist/packages/mcp/src/paper-agent.js +2 -0
- package/dist/packages/mcp/src/server.js +127 -19
- package/dist/packages/packs/src/backtest.js +3 -1
- package/dist/packages/popup/src/pages/chart-lib.js +134 -21
- package/dist/packages/popup/src/pages/chart.css +9 -0
- package/dist/packages/popup/src/pages/chart.html +3 -1
- package/dist/packages/popup/src/pages/chart.js +104 -7
- package/dist/packages/popup/src/protocol.js +2 -0
- package/dist/packages/popup/src/server.js +4 -0
- package/dist/packages/recorder/src/index.js +2 -0
- package/dist/packages/recorder/src/recorder.js +63 -6
- package/dist/packages/recorder/src/retention.js +100 -0
- package/dist/packages/recorder/src/schema.js +34 -1
- package/dist/packages/recorder/src/ticks.js +237 -0
- package/dist/packages/tui/src/index.js +1 -0
- package/dist/packages/tui/src/keymap.js +21 -1
- package/dist/packages/tui/src/markers.js +219 -0
- package/dist/packages/tui/src/widgets.js +149 -2
- package/package.json +2 -1
- package/dist/packages/data/src/trade/caps.js +0 -323
- package/dist/packages/data/src/trade/executor.js +0 -933
- package/dist/packages/data/src/trade/plans/executor-live.js +0 -220
- package/dist/packages/data/src/trade/rpc-exec.js +0 -229
- package/dist/packages/data/src/trade/signer/client.js +0 -197
- package/dist/packages/data/src/trade/signer/fast-wallet.js +0 -154
- package/dist/packages/data/src/trade/signer/host.js +0 -97
- package/dist/packages/data/src/trade/signer/main.js +0 -121
- package/dist/packages/data/src/trade/signer/probe-builder.js +0 -85
- package/dist/packages/data/src/trade/signer/protocol.js +0 -92
- package/dist/packages/data/src/trade/signer/service.js +0 -400
- package/dist/packages/data/src/trade/signer/sol-usd-feed.js +0 -98
- package/dist/packages/data/src/trade/sol-usd.js +0 -86
- package/dist/packages/data/src/trade/swap-build.js +0 -108
- package/dist/packages/data/src/trade/token-delta.js +0 -201
- package/dist/packages/data/vendor/solana-web3/LICENSE +0 -20
- package/dist/packages/data/vendor/solana-web3/NOTICE.md +0 -13
- package/dist/packages/data/vendor/solana-web3/index.iife.min.js +0 -20
- package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-a-live-ticket.md +0 -42
- package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-before-you-press-size-vs-caps.md +0 -34
- package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-devnet-signer-mainnet-token.md +0 -35
- package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-jupiter-rate-limits.md +0 -33
- package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-link-a-wallet.md +0 -32
- package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-live-trading-devnet-first.md +0 -30
- package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-mainnet.md +0 -31
- package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-the-live-fire-path-devnet-the-fast-wallet.md +0 -41
- package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-the-signer-process.md +0 -34
- package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-what-the-live-path-keeps.md +0 -37
- package/dist/packages/mcp/assets/kb/docs/docs-paper-trading-your-first-live-trade.md +0 -41
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
//
|
|
10
10
|
// No network calls, nothing here is read by the signer, the caps, tickets, plans or the confirm gate.
|
|
11
11
|
import { fmtMcap, fmtCompact, fmtPrice } from '../../tui/src/index.js';
|
|
12
|
-
import { applyAndJournal, configPath, dextermHome, loadConfig, DEFAULT_PRICE_MODE, PRICE_MODES, CHART_AXES, DEFAULT_CHART_AXIS } from '../../custom/src/index.js';
|
|
13
|
-
|
|
12
|
+
import { applyAndJournal, configPath, dextermHome, loadConfig, DEFAULT_PRICE_MODE, PRICE_MODES, CHART_AXES, DEFAULT_CHART_AXIS, CHART_MARKERS, DEFAULT_CHART_MARKERS } from '../../custom/src/index.js';
|
|
13
|
+
import { knownSupply, pickBasis, PRICE_BASIS_ENV } from '../../data/src/basis.js';
|
|
14
|
+
export { PRICE_MODES, DEFAULT_PRICE_MODE, CHART_AXES, DEFAULT_CHART_AXIS, CHART_MARKERS, DEFAULT_CHART_MARKERS };
|
|
14
15
|
/** Axis / caption label for an mcap chart: the history is scaled by today's supply, and says so. */
|
|
15
16
|
export const MCAP_AXIS_LABEL = 'mcap (current supply)';
|
|
16
17
|
/** Shown wherever mcap mode is on but a token's supply is unknown, so the number on screen is a price. */
|
|
@@ -142,29 +143,65 @@ export function positionPriceCells(mode, supply, avgUsd, priceUsd, avgText, pric
|
|
|
142
143
|
const mark = mode === 'mcap' ? FALLBACK_MARK : '';
|
|
143
144
|
return { avg: { label: 'AVG ENTRY', value: avgText === '—' ? avgText : avgText + mark }, price: { label: 'PRICE', value: priceText === '—' ? priceText : priceText + mark } };
|
|
144
145
|
}
|
|
145
|
-
/**
|
|
146
|
+
/**
|
|
147
|
+
* task-1537: the known supply for a coin the app is showing: the open token view's (mcap ÷ price at its latest tick),
|
|
148
|
+
* else its screener row's, else pump.fun's fixed 1B (the PnL card's rule, @dexterm/data/basis knownSupply). Never
|
|
149
|
+
* guessed: null means the caller shows the price and marks it.
|
|
150
|
+
*/
|
|
151
|
+
export function supplyForMint(state, mint) {
|
|
152
|
+
if (!mint)
|
|
153
|
+
return null;
|
|
154
|
+
const v = state.live?.token?.view;
|
|
155
|
+
if (v && v.mint === mint) {
|
|
156
|
+
const r = supplyRatio(v.price, v.mcap);
|
|
157
|
+
if (r !== null)
|
|
158
|
+
return r;
|
|
159
|
+
}
|
|
160
|
+
const row = state.screener?.rows.find((x) => x.mint === mint);
|
|
161
|
+
if (row) {
|
|
162
|
+
const r = supplyRatio(row.price, row.mcap);
|
|
163
|
+
if (r !== null)
|
|
164
|
+
return r;
|
|
165
|
+
}
|
|
166
|
+
return knownSupply({ mint, launchpad: row?.launchpad ?? (v && v.mint === mint ? v.launchpad : null) })?.tokens ?? null;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* task-1537: one more price LEVEL in a row (a stop, a target, a fill, a tape trade): its market cap at the given supply
|
|
170
|
+
* in mcap mode, else the price (marked ᵖ when mcap mode had no supply). Display only.
|
|
171
|
+
*/
|
|
172
|
+
export function levelCell(mode, supply, usd) {
|
|
173
|
+
if (usd === null || usd === undefined || !Number.isFinite(usd))
|
|
174
|
+
return '—';
|
|
175
|
+
if (mode === 'mcap' && supply != null && supply > 0)
|
|
176
|
+
return fmtMcap(usd * supply);
|
|
177
|
+
return fmtPrice(usd) + (mode === 'mcap' ? FALLBACK_MARK : '');
|
|
178
|
+
}
|
|
179
|
+
/** The mode in effect: the state's (set from config, a workspace, `$` or a one-run override), default MARKET CAP (task-1537). */
|
|
146
180
|
export function priceModeOf(state) {
|
|
147
|
-
return state?.priceMode === '
|
|
181
|
+
return state?.priceMode === 'price' ? 'price' : 'mcap';
|
|
148
182
|
}
|
|
149
|
-
/**
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
183
|
+
/**
|
|
184
|
+
* The mode a run starts in: the one-run override (`DEXTERM_PRICE_BASIS=price|mcap`, which `--price` / `--mcap` /
|
|
185
|
+
* `--price-mode` also set), else config.display.priceMode, else market cap (task-1537: @dexterm/data/basis pickBasis).
|
|
186
|
+
*/
|
|
187
|
+
export function configPriceMode(cfg, env) {
|
|
188
|
+
return pickBasis(cfg?.display?.priceMode, env);
|
|
153
189
|
}
|
|
154
190
|
/**
|
|
155
|
-
*
|
|
156
|
-
*
|
|
191
|
+
* `$` (and `/display mcap|price` in the chat box, task-1537): set the mode (`next` absent = flip) and persist it to
|
|
192
|
+
* config.display.priceMode through the journal (actor user, so `undo` works). Returns the notice for the toast.
|
|
193
|
+
* Persistence failure keeps the new mode for this run and says why.
|
|
157
194
|
*/
|
|
158
|
-
export function
|
|
159
|
-
const
|
|
160
|
-
state.priceMode =
|
|
161
|
-
const what =
|
|
195
|
+
export function setPriceMode(state, next, why = '$') {
|
|
196
|
+
const mode = next ?? (priceModeOf(state) === 'mcap' ? 'price' : 'mcap');
|
|
197
|
+
state.priceMode = mode;
|
|
198
|
+
const what = mode === 'mcap' ? 'showing MARKET CAP' : 'showing USD PRICE'; // task-1472: the charts follow A, not $
|
|
162
199
|
const ui = state.custom;
|
|
163
200
|
if (!ui)
|
|
164
201
|
return `${what} (not saved: no config on this run)`;
|
|
165
202
|
try {
|
|
166
|
-
const op = ui.config.display ? { op: 'add', path: '/display/priceMode', value:
|
|
167
|
-
const { config } = applyAndJournal(ui.home, [op], { actor: 'user', why: `$ price mode ${
|
|
203
|
+
const op = ui.config.display ? { op: 'add', path: '/display/priceMode', value: mode } : { op: 'add', path: '/display', value: { priceMode: mode } };
|
|
204
|
+
const { config } = applyAndJournal(ui.home, [op], { actor: 'user', why: `${why} price mode ${mode}`, now: state.now.getTime() });
|
|
168
205
|
ui.config = config;
|
|
169
206
|
return `${what} · saved ($ to switch back)`;
|
|
170
207
|
}
|
|
@@ -172,6 +209,49 @@ export function togglePriceMode(state) {
|
|
|
172
209
|
return `${what} (not saved: ${e.message})`;
|
|
173
210
|
}
|
|
174
211
|
}
|
|
212
|
+
/** `$`: flip the mode and persist it (see setPriceMode). */
|
|
213
|
+
export function togglePriceMode(state) { return setPriceMode(state); }
|
|
214
|
+
/**
|
|
215
|
+
* task-1537: the chat box command for the price basis, never sent to a model: `/display` (show), `/display mcap|price`,
|
|
216
|
+
* `/basis mcap|price`, `/set basis mcap|price` (also `/set priceMode …`). null = not this command.
|
|
217
|
+
*/
|
|
218
|
+
export function parseDisplayCommand(q) {
|
|
219
|
+
const w = q.trim().replace(/^\//, '').split(/\s+/).filter(Boolean).map((x) => x.toLowerCase());
|
|
220
|
+
let arg;
|
|
221
|
+
if (w[0] === 'display' || w[0] === 'basis') {
|
|
222
|
+
if (w[1] === 'markers')
|
|
223
|
+
return null;
|
|
224
|
+
arg = w[1];
|
|
225
|
+
}
|
|
226
|
+
else if (w[0] === 'set' && (w[1] === 'basis' || w[1] === 'pricemode' || w[1] === 'price-basis' || w[1] === 'display.pricemode'))
|
|
227
|
+
arg = w[2];
|
|
228
|
+
else
|
|
229
|
+
return null;
|
|
230
|
+
if (arg === undefined)
|
|
231
|
+
return { show: true };
|
|
232
|
+
return isPriceMode(arg) ? { mode: arg } : { error: `/display expects mcap or price, got ${JSON.stringify(arg.slice(0, 20))}` };
|
|
233
|
+
}
|
|
234
|
+
/** The toast for `/display` with no argument. */
|
|
235
|
+
export function priceModeNotice(state) {
|
|
236
|
+
return priceModeOf(state) === 'mcap'
|
|
237
|
+
? 'price basis: MARKET CAP (default) · coins with no known supply show price ᵖ · /display price or $ to switch'
|
|
238
|
+
: 'price basis: USD PRICE · /display mcap or $ to switch back to market cap';
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* task-1537: the one-run basis flags, accepted before any subcommand (`dexterm --price positions`, `dexterm autotrade
|
|
242
|
+
* list --mcap`): `--price` / `--mcap` are removed from argv and set DEXTERM_PRICE_BASIS in `env` for this process (so
|
|
243
|
+
* child agents and every CLI text follow it); nothing is saved. Returns argv without them.
|
|
244
|
+
*/
|
|
245
|
+
export function takeBasisFlags(argv, env) {
|
|
246
|
+
const out = [];
|
|
247
|
+
for (const a of argv) {
|
|
248
|
+
if (a === '--price' || a === '--mcap')
|
|
249
|
+
env[PRICE_BASIS_ENV] = a.slice(2);
|
|
250
|
+
else
|
|
251
|
+
out.push(a);
|
|
252
|
+
}
|
|
253
|
+
return out;
|
|
254
|
+
}
|
|
175
255
|
export function isChartAxis(v) { return CHART_AXES.includes(v); }
|
|
176
256
|
/** task-1472: the chart Y axis in effect: the state's (from config or `A`), default MARKET CAP. */
|
|
177
257
|
export function chartAxisOf(state) {
|
|
@@ -203,7 +283,38 @@ export function setChartAxis(state, next) {
|
|
|
203
283
|
return `${what} (not saved: ${e.message})`;
|
|
204
284
|
}
|
|
205
285
|
}
|
|
206
|
-
export
|
|
286
|
+
export function isChartMarkers(v) { return CHART_MARKERS.includes(v); }
|
|
287
|
+
/** task-1483: are the BUY / SELL markers on (both charts)? Default on; only an explicit 'off' hides them. */
|
|
288
|
+
export function chartMarkersOn(state) {
|
|
289
|
+
return state?.chartMarkers !== 'off';
|
|
290
|
+
}
|
|
291
|
+
/** task-1483: the markers setting a run starts with: config.display.chartMarkers, else on. */
|
|
292
|
+
export function configChartMarkers(cfg) {
|
|
293
|
+
const m = cfg?.display?.chartMarkers;
|
|
294
|
+
return isChartMarkers(m) ? m : DEFAULT_CHART_MARKERS;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* task-1483: show / hide the chart BUY / SELL markers (both chart surfaces) and persist config.display.chartMarkers through
|
|
298
|
+
* the journal (actor user, so `undo` works). `next` absent = flip. Returns the toast text. Display only.
|
|
299
|
+
*/
|
|
300
|
+
export function setChartMarkers(state, next) {
|
|
301
|
+
const v = next ?? (chartMarkersOn(state) ? 'off' : 'on');
|
|
302
|
+
state.chartMarkers = v;
|
|
303
|
+
const what = v === 'on' ? 'chart BUY/SELL markers: ON' : 'chart BUY/SELL markers: OFF';
|
|
304
|
+
const ui = state.custom;
|
|
305
|
+
if (!ui)
|
|
306
|
+
return `${what} (not saved: no config on this run)`;
|
|
307
|
+
try {
|
|
308
|
+
const op = ui.config.display ? { op: 'add', path: '/display/chartMarkers', value: v } : { op: 'add', path: '/display', value: { chartMarkers: v } };
|
|
309
|
+
const { config } = applyAndJournal(ui.home, [op], { actor: 'user', why: `chart markers ${v}`, now: state.now.getTime() });
|
|
310
|
+
ui.config = config;
|
|
311
|
+
return `${what} · saved`;
|
|
312
|
+
}
|
|
313
|
+
catch (e) {
|
|
314
|
+
return `${what} (not saved: ${e.message})`;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
export const DISPLAY_USAGE = 'usage: dexterm display [price|mcap] show or set display.priceMode in ~/.dexterm/config.json ($ in the app toggles it)\n dexterm display markers [on|off] show or set display.chartMarkers (BUY/SELL markers on both charts)';
|
|
207
318
|
/** `dexterm display [price|mcap]`: print the saved price display mode, or set it (journaled, actor user). No network. */
|
|
208
319
|
export function displayCommand(argv, io) {
|
|
209
320
|
const home = dextermHome(io.env);
|
|
@@ -218,6 +329,34 @@ export function displayCommand(argv, io) {
|
|
|
218
329
|
io.stdout.write(`display.priceMode = ${m}${m === 'mcap' ? ' (tables show MCAP; tokens without a supply fall back to price)' : ' (USD price per token)'}\n`);
|
|
219
330
|
const a = configChartAxis(loaded.config);
|
|
220
331
|
io.stdout.write(`display.chartAxis = ${a}${a === 'mcap' ? ` (charts: ${MCAP_AXIS_LABEL}; A switches)` : ' (charts plot USD price; A switches)'}\n`);
|
|
332
|
+
const mk = configChartMarkers(loaded.config);
|
|
333
|
+
io.stdout.write(`display.chartMarkers = ${mk}${mk === 'on' ? ' (charts mark your paper and live fills; dexterm display markers off hides them)' : ' (no fill markers on the charts)'}\n`);
|
|
334
|
+
return 0;
|
|
335
|
+
}
|
|
336
|
+
// task-1483: `dexterm display markers [on|off]`
|
|
337
|
+
if (arg === 'markers') {
|
|
338
|
+
const v = argv[1];
|
|
339
|
+
if (v === undefined) {
|
|
340
|
+
if (!loaded.ok) {
|
|
341
|
+
io.stderr.write(`dexterm display: ${loaded.errors[0]}\n`);
|
|
342
|
+
return 1;
|
|
343
|
+
}
|
|
344
|
+
io.stdout.write(`display.chartMarkers = ${configChartMarkers(loaded.config)}\n`);
|
|
345
|
+
return 0;
|
|
346
|
+
}
|
|
347
|
+
if (!isChartMarkers(v)) {
|
|
348
|
+
io.stderr.write(`dexterm display markers: expected on or off, got ${JSON.stringify(v.slice(0, 20))}\n${DISPLAY_USAGE}\n`);
|
|
349
|
+
return 2;
|
|
350
|
+
}
|
|
351
|
+
try {
|
|
352
|
+
const op = loaded.config.display ? { op: 'add', path: '/display/chartMarkers', value: v } : { op: 'add', path: '/display', value: { chartMarkers: v } };
|
|
353
|
+
applyAndJournal(home, [op], { actor: 'user', why: `dexterm display markers ${v}` });
|
|
354
|
+
}
|
|
355
|
+
catch (e) {
|
|
356
|
+
io.stderr.write(`dexterm display: ${e.message}\n`);
|
|
357
|
+
return 1;
|
|
358
|
+
}
|
|
359
|
+
io.stdout.write(`display.chartMarkers = ${v} (saved to ${configPath(home)})\n`);
|
|
221
360
|
return 0;
|
|
222
361
|
}
|
|
223
362
|
if (!isPriceMode(arg)) {
|
|
@@ -18,6 +18,7 @@ import { SayTts, voiceDoctor, resolveVoice, WHISPER_MODEL, resolvePiperRuntime,
|
|
|
18
18
|
import { loadConfig, dextermHome } from '../../custom/src/index.js';
|
|
19
19
|
import { kbStore, skillStore } from "./kb-skill-cmd.js";
|
|
20
20
|
import { analystCliOnPath, CODEX_MIN_VERSION, parseEngineChoice, resolveEngine, versionAtLeast } from "./analyst/codex.js";
|
|
21
|
+
import { OllamaClient, SUGGESTED_MODELS, SURFACES, belowBar, effectiveRestriction, engineChoiceFor, loadAiConfig, ollamaSettings, pickModel, probeModel, remoteHostWarning } from '../../mcp/src/engine/index.js';
|
|
21
22
|
/** The minimum Node that runs dexterm (type-stripping of the .ts entry needs 22.18). */
|
|
22
23
|
export const MIN_NODE = [22, 18, 0];
|
|
23
24
|
/** Cheap PATH lookup (no spawn). Windows (task-1423): PATH is `;`-separated and commands carry an extension
|
|
@@ -142,6 +143,18 @@ export async function claudeProbe(timeoutMs = 4000, platform = process.platform,
|
|
|
142
143
|
}
|
|
143
144
|
});
|
|
144
145
|
}
|
|
146
|
+
/** Default Ollama facts: ai.json + a short probe of the configured host (127.0.0.1 by default). Never throws. */
|
|
147
|
+
export async function ollamaFacts(env = process.env) {
|
|
148
|
+
const c = loadAiConfig(env).config;
|
|
149
|
+
const set = ollamaSettings(c, env);
|
|
150
|
+
const client = new OllamaClient({ host: set.host, metaTimeoutMs: 2500 });
|
|
151
|
+
const probe = await probeModel(client, set.model, { numCtx: set.numCtx });
|
|
152
|
+
if (!probe.model && probe.models.length)
|
|
153
|
+
probe.model = null;
|
|
154
|
+
const surfaces = SURFACES.filter((sf) => engineChoiceFor(sf, c, env) === 'ollama');
|
|
155
|
+
const eff = effectiveRestriction(c, set.model ?? pickModel(probe.models), env);
|
|
156
|
+
return { probe, setUp: !!set.model || surfaces.length > 0, surfaces, level: eff.level, note: eff.note, hostWarning: remoteHostWarning(set.host) };
|
|
157
|
+
}
|
|
145
158
|
/**
|
|
146
159
|
* Default codex probe (0.1.5): PATH (spawnable form only), then `codex --version` and `codex login status`. The
|
|
147
160
|
* status command is the user's own CLI reporting on its own login; dexterm never reads the credential itself.
|
|
@@ -190,6 +203,7 @@ export function defaultDeps(env = process.env, isTTY = process.stdout.isTTY ===
|
|
|
190
203
|
platform: process.platform,
|
|
191
204
|
claude: () => claudeProbe(),
|
|
192
205
|
codex: () => codexProbe(4000, env),
|
|
206
|
+
ollama: () => ollamaFacts(env),
|
|
193
207
|
analystEngine: env.DEXTERM_ANALYST_ENGINE ?? loadConfig(dextermHome(env)).config.analyst?.engine ?? null,
|
|
194
208
|
probe: (url) => livingProbe(url),
|
|
195
209
|
checkWritable: writableProbe,
|
|
@@ -262,7 +276,16 @@ export async function runDoctor(deps) {
|
|
|
262
276
|
// 0.1.5: codex is the optional second engine; a missing claude is fine when codex can run the analyst.
|
|
263
277
|
const codex = deps.codex ? await deps.codex() : null;
|
|
264
278
|
const codexUsable = codex?.state === 'present';
|
|
265
|
-
|
|
279
|
+
// task-1543: a reachable Ollama with a pulled model can run the analyst too (a free local engine).
|
|
280
|
+
const ol = deps.ollama ? await deps.ollama().catch(() => null) : null;
|
|
281
|
+
const ollamaUsable = !!ol && ol.probe.reachable && (ol.probe.model ? ol.probe.present : ol.probe.models.length > 0);
|
|
282
|
+
if (claude === 'missing' && !codexUsable && ollamaUsable) {
|
|
283
|
+
checks.push({
|
|
284
|
+
name: 'Claude CLI', status: 'pass',
|
|
285
|
+
detail: 'not found on PATH (optional now): the analyst runs on your local Ollama model instead',
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
else if (claude === 'missing' && codexUsable) {
|
|
266
289
|
checks.push({
|
|
267
290
|
name: 'Claude CLI', status: 'pass',
|
|
268
291
|
detail: 'not found on PATH (optional now): the analyst runs on your codex CLI instead',
|
|
@@ -272,7 +295,7 @@ export async function runDoctor(deps) {
|
|
|
272
295
|
checks.push({
|
|
273
296
|
name: 'Claude CLI', status: 'warn',
|
|
274
297
|
detail: 'not found on PATH; the analyst (a) is disabled, the rest of dexterm works',
|
|
275
|
-
fix: '
|
|
298
|
+
fix: 'Set up an AI backend: install Claude Code (https://claude.com/claude-code) and run `claude` once to log in, or Codex (`npm i -g @openai/codex && codex login`), or a free local model (install Ollama from https://ollama.com/download, `ollama pull qwen3:8b`, `dexterm ai engine ollama`).',
|
|
276
299
|
});
|
|
277
300
|
}
|
|
278
301
|
else {
|
|
@@ -284,7 +307,7 @@ export async function runDoctor(deps) {
|
|
|
284
307
|
// 3b. Codex CLI (0.1.5): optional second analyst engine, the user's own codex login. Read-only lock needs >= CODEX_MIN_VERSION.
|
|
285
308
|
if (codex) {
|
|
286
309
|
const choice = parseEngineChoice(deps.analystEngine) ?? 'auto';
|
|
287
|
-
const engine = resolveEngine(choice, (b) => b === 'claude' ? claude !== 'missing' : codexUsable);
|
|
310
|
+
const engine = resolveEngine(choice, (b) => b === 'claude' ? claude !== 'missing' : b === 'codex' ? codexUsable : ollamaUsable && !!ol?.setUp);
|
|
288
311
|
const eng = `analyst engine: ${engine}${choice === 'auto' ? ' (auto)' : ''}`;
|
|
289
312
|
if (codex.state === 'missing') {
|
|
290
313
|
checks.push({ name: 'Codex CLI', status: engine === 'codex' ? 'warn' : 'pass', detail: `not installed (optional second analyst engine) · ${eng}`, ...(engine === 'codex' ? { fix: 'npm i -g @openai/codex && codex login, or set analyst.engine to claude' } : {}) });
|
|
@@ -299,6 +322,9 @@ export async function runDoctor(deps) {
|
|
|
299
322
|
checks.push({ name: 'Codex CLI', status: 'pass', detail: `found${codex.version ? ` (codex-cli ${codex.version})` : ''}${codex.loggedIn ? ', logged in' : ''}; runs the analyst read-only on your own codex login (/engine codex) · ${eng}` });
|
|
300
323
|
}
|
|
301
324
|
}
|
|
325
|
+
// 3c. Local engine (task-1543): the user's own Ollama on this machine, the model, tool calling, context, profile.
|
|
326
|
+
if (ol)
|
|
327
|
+
checks.push(ollamaCheck(ol, claude !== 'missing' || codexUsable));
|
|
302
328
|
// 4b. Login with X (optional, task-1357): the user's own X app + login unlock X posts in the SOCIAL panel / TRENDING.
|
|
303
329
|
{
|
|
304
330
|
const xs = new XTokenStore({ env: deps.env });
|
|
@@ -445,3 +471,36 @@ export function renderDoctor(result, opts = {}) {
|
|
|
445
471
|
lines.push(paint(`${fails} check${fails === 1 ? '' : 's'} failed — fix the ✗ lines above, then re-run \`dexterm doctor\`.`, color ? ANSI.fail : ''));
|
|
446
472
|
return lines.join('\n');
|
|
447
473
|
}
|
|
474
|
+
/**
|
|
475
|
+
* The Ollama line (task-1543). Optional while claude/codex can run the analyst; a warning with the 2-minute
|
|
476
|
+
* setup when nothing can, or when the user chose ollama and it is not ready.
|
|
477
|
+
*/
|
|
478
|
+
export function ollamaCheck(o, otherEngine) {
|
|
479
|
+
const p = o.probe;
|
|
480
|
+
const pull = `ollama pull ${SUGGESTED_MODELS[0].name}`;
|
|
481
|
+
const setup = `Install Ollama (https://ollama.com/download) and open it, then \`${pull}\` and \`dexterm ai engine ollama\` (\`dexterm ai model ${SUGGESTED_MODELS[0].name}\`).`;
|
|
482
|
+
const used = o.surfaces.length ? ` · runs: ${o.surfaces.join(', ')}` : '';
|
|
483
|
+
const prof = ` · profile ${o.level}${o.note ? ` (${o.note})` : ''}`;
|
|
484
|
+
const remote = o.hostWarning ? ` · WARNING ${o.hostWarning}` : '';
|
|
485
|
+
if (!p.reachable) {
|
|
486
|
+
// task-1551: a redirect is refused before anything is sent on; say so, whatever the setup state.
|
|
487
|
+
if (p.redirect)
|
|
488
|
+
return { name: 'Ollama (local AI)', status: 'warn', detail: `${p.host} answered with a redirect: refused, nothing was sent on${used}${remote}`, fix: 'dexterm never follows a redirect for the local engine (it would send your prompt to another host). Point it at the Ollama server itself with `dexterm ai host <host:port>` (or DEXTERM_OLLAMA_HOST), then re-run `dexterm doctor`.' };
|
|
489
|
+
if (!o.setUp)
|
|
490
|
+
return otherEngine
|
|
491
|
+
? { name: 'Ollama (local AI)', status: 'pass', detail: 'not set up (optional free local engine; no login, no key, nothing leaves this machine)' }
|
|
492
|
+
: { name: 'Ollama (local AI)', status: 'warn', detail: 'no AI engine on this machine yet: a free local model works without any login or key', fix: setup };
|
|
493
|
+
return { name: 'Ollama (local AI)', status: 'warn', detail: `not reachable at ${p.host}${used}${remote}`, fix: `Start Ollama (open the app, or run \`ollama serve\`), then re-run \`dexterm doctor\`. Not installed? ${setup}` };
|
|
494
|
+
}
|
|
495
|
+
if (!p.model) {
|
|
496
|
+
const pick = pickModel(p.models);
|
|
497
|
+
return { name: 'Ollama (local AI)', status: o.setUp || !otherEngine ? 'warn' : 'pass', detail: `Ollama ${p.version ?? ''} running · pulled: ${p.models.slice(0, 5).join(', ') || 'none'} · no model chosen${used}${remote}`, ...(o.setUp || !otherEngine ? { fix: pick ? `dexterm ai model ${pick}` : `${pull} && dexterm ai model ${SUGGESTED_MODELS[0].name}` } : {}) };
|
|
498
|
+
}
|
|
499
|
+
if (!p.present)
|
|
500
|
+
return { name: 'Ollama (local AI)', status: 'warn', detail: `${p.model} is not pulled on ${p.host}${used}${remote}`, fix: `ollama pull ${p.model}` };
|
|
501
|
+
const warns = belowBar(o.level, p);
|
|
502
|
+
const facts = `${p.model} · tools ${p.tools === null ? '?' : p.tools ? 'yes' : 'no'} · context ${p.contextLength ?? '?'}`;
|
|
503
|
+
if (warns.length || o.hostWarning)
|
|
504
|
+
return { name: 'Ollama (local AI)', status: 'warn', detail: `${facts}${used}${prof}${remote}${warns.length ? ` · ${warns[0]}` : ''}`, fix: warns.length ? `\`dexterm ai probe --json\` checks it in detail; pull a stronger tool-capable model (e.g. ${pull}) or lower the profile (\`dexterm ai restrictions observe\`).` : 'Point dexterm at this machine: dexterm ai host 127.0.0.1' };
|
|
505
|
+
return { name: 'Ollama (local AI)', status: 'pass', detail: `${facts} · ${p.local ? 'local' : 'remote'} · $0${used}${prof}` };
|
|
506
|
+
}
|
|
@@ -12,6 +12,7 @@ import { mkdirSync, writeFileSync } from 'node:fs';
|
|
|
12
12
|
import { join } from 'node:path';
|
|
13
13
|
import { Canvas, rasterizeCanvas, fmtUsd, fmtPrice, fmtPct } from '../../tui/src/index.js';
|
|
14
14
|
import { encodePng } from '../../data/src/index.js';
|
|
15
|
+
import { priceModeOf } from "./display.js";
|
|
15
16
|
import { dextermHome } from "./boot-state.js";
|
|
16
17
|
import { cleanText } from "./screener/rows.js";
|
|
17
18
|
import { rugP, fmtRugP, RUG_MODEL_LABEL } from "./screener/rug.js";
|
|
@@ -152,8 +153,15 @@ const yesNo = (b) => (b === null ? 'unknown' : b ? 'ENABLED' : 'revoked');
|
|
|
152
153
|
export function tokenReport(state, v, now) {
|
|
153
154
|
const L = [];
|
|
154
155
|
L.push(`coin $${cleanText(v.symbol, 16)}${v.name ? ` · ${cleanText(v.name, 40)}` : ''} · ${v.launchpad}`);
|
|
155
|
-
|
|
156
|
-
|
|
156
|
+
const moves = `5m ${fmtPct(v.chg.m5)} 1h ${fmtPct(v.chg.h1)} 6h ${fmtPct(v.chg.h6)} 24h ${fmtPct(v.chg.h24)}`;
|
|
157
|
+
if (priceModeOf(state) === 'mcap' && v.mcap !== null) { // task-1537: the market cap leads by default; both numbers stay
|
|
158
|
+
L.push(`market cap ${fmtUsd(v.mcap)}${v.mcapFlagged ? ' (flagged)' : ''} price ${fmtPrice(v.price)} ${moves}`);
|
|
159
|
+
L.push(`liquidity ${fmtUsd(v.liq)} vol 24h ${fmtUsd(v.vol24)}`);
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
L.push(`price ${fmtPrice(v.price)} ${moves}`);
|
|
163
|
+
L.push(`market cap ${fmtUsd(v.mcap)}${v.mcapFlagged ? ' (flagged)' : ''} liquidity ${fmtUsd(v.liq)} vol 24h ${fmtUsd(v.vol24)}`);
|
|
164
|
+
}
|
|
157
165
|
L.push(`holders ${v.holders ?? '—'} top-10 ${v.top10 === null ? '—' : `${v.top10.toFixed(1)}%`} dev ${v.dev === null ? '—' : `${v.dev.toFixed(1)}%`}${v.holdersSample ? ` (${v.holdersSample})` : ''}`);
|
|
158
166
|
L.push(`age ${v.ageMin === null ? '—' : fmtAge(v.ageMin * 60)}`);
|
|
159
167
|
L.push(`authorities mint ${yesNo(v.mintAuth)} · freeze ${yesNo(v.freezeAuth)}${v.riskyExtensions.length ? ` · risky extensions: ${v.riskyExtensions.join(', ')}` : ''}`);
|
|
@@ -19,7 +19,7 @@ export { renderAnalyst, renderContextRail, renderCoinList } from "./screens/anal
|
|
|
19
19
|
export { renderTicket } from "./screens/ticket.js";
|
|
20
20
|
export { renderPositions } from "./screens/positions.js";
|
|
21
21
|
export * from "./trade.js";
|
|
22
|
-
export { TradeTicketLive, PositionsLive,
|
|
22
|
+
export { TradeTicketLive, PositionsLive, POSITIONS_REFRESH_MS } from "./live/trade.js";
|
|
23
23
|
export { parseWalletCommand, WALLET_HELP } from "./wallet-command.js";
|
|
24
24
|
export * from "./screener/filter.js";
|
|
25
25
|
export * from "./screener/sort.js";
|