dexterm-cli 0.1.5 → 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/index.js +2 -0
- package/dist/packages/agents/src/schema.js +22 -1
- package/dist/packages/agents/src/spectator.js +54 -0
- package/dist/packages/agents/src/story.js +532 -0
- package/dist/packages/agents/src/tiers.js +28 -2
- package/dist/packages/agents/src/tools.js +31 -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/REGISTRY.json +1 -1
- package/dist/packages/cli/assets/claude/plugin/skills/larp-check/SKILL.md +15 -8
- package/dist/packages/cli/assets/claude/plugin/skills/token-dossier/SKILL.md +1 -1
- package/dist/packages/cli/src/agent-cmd.js +6 -4
- package/dist/packages/cli/src/agent-spectator.js +17 -1
- package/dist/packages/cli/src/ai-cmd.js +412 -0
- package/dist/packages/cli/src/analyst/backend.js +105 -15
- package/dist/packages/cli/src/analyst/codex.js +14 -9
- package/dist/packages/cli/src/analyst/larp-gauge.js +60 -0
- package/dist/packages/cli/src/analyst/ollama.js +263 -0
- package/dist/packages/cli/src/analyst/session.js +17 -3
- package/dist/packages/cli/src/app-help-gen.js +51 -15
- 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/backtest-cmd.js +13 -2
- package/dist/packages/cli/src/display.js +208 -23
- 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/dev-history.js +31 -15
- package/dist/packages/cli/src/live/index.js +28 -90
- package/dist/packages/cli/src/live/screens/newpairs-live.js +1 -1
- package/dist/packages/cli/src/live/screens/token-live.js +48 -15
- package/dist/packages/cli/src/live/screens/watchlist-live.js +1 -1
- package/dist/packages/cli/src/live/trade.js +30 -453
- package/dist/packages/cli/src/live/watchlist.js +1 -1
- package/dist/packages/cli/src/main.js +290 -199
- package/dist/packages/cli/src/mcp-cmd.js +7 -1
- package/dist/packages/cli/src/mcp-follow.js +103 -6
- package/dist/packages/cli/src/plan-cmd.js +15 -5
- 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 +38 -6
- package/dist/packages/cli/src/record-cmd.js +141 -20
- package/dist/packages/cli/src/scan/ui.js +7 -1
- package/dist/packages/cli/src/screens/agent-hud.js +773 -0
- package/dist/packages/cli/src/screens/analyst-session.js +11 -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 +634 -0
- package/dist/packages/cli/src/screens/newpairs.js +1 -1
- 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 +144 -0
- package/dist/packages/cli/src/screens/positions.js +6 -28
- package/dist/packages/cli/src/screens/screener.js +1 -0
- package/dist/packages/cli/src/screens/ticket.js +38 -205
- package/dist/packages/cli/src/screens/token.js +18 -9
- package/dist/packages/cli/src/screens/trending.js +1 -1
- package/dist/packages/cli/src/state.js +88 -18
- 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 +41 -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 +2 -14
- package/dist/packages/data/src/larp/score.js +220 -0
- package/dist/packages/data/src/larp/x-account.js +316 -0
- package/dist/packages/data/src/store.js +14 -5
- package/dist/packages/data/src/trade/agent/paper-desk.js +300 -23
- 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/engine.js +7 -0
- package/dist/packages/data/src/trade/plans/index.js +0 -1
- package/dist/packages/data/src/trade/plans/mandate.js +28 -15
- package/dist/packages/data/src/trade/plans/service.js +4 -28
- 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/dev-history.md +1 -1
- package/dist/packages/mcp/assets/kb/app-help/larp-check.md +5 -1
- 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/scan-mode.md +1 -1
- 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 +6 -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/spectate-an-agent.md +2 -1
- 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 +7 -3
- 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-starting-a-run.md +2 -0
- 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 +32 -0
- 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 +9 -7
- 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-running-the-tests.md +1 -1
- package/dist/packages/mcp/assets/kb/docs/docs-getting-started.md +1 -1
- package/dist/packages/mcp/assets/kb/docs/docs-larp-measured-accuracy.md +1 -0
- package/dist/packages/mcp/assets/kb/docs/docs-larp-the-larp-score.md +60 -0
- package/dist/packages/mcp/assets/kb/docs/docs-larp-the-verdict.md +0 -2
- package/dist/packages/mcp/assets/kb/docs/docs-larp-what-it-looks-at.md +4 -1
- package/dist/packages/mcp/assets/kb/docs/docs-larp.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 +4 -13
- 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 +40 -0
- 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-market-cap-axis.md +1 -1
- package/dist/packages/mcp/assets/kb/docs/docs-popup-chart-what-it-shows.md +3 -1
- package/dist/packages/mcp/assets/kb/docs/docs-scan-the-read.md +2 -0
- package/dist/packages/mcp/assets/kb/docs/docs-screens-autotrade-paper.md +26 -0
- package/dist/packages/mcp/assets/kb/docs/docs-screens-dev-history.md +10 -7
- 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-follow-over-mcp-in-the-running-terminal.md +1 -1
- package/dist/packages/mcp/assets/kb/docs/docs-spectator-limits.md +2 -0
- package/dist/packages/mcp/assets/kb/docs/docs-spectator-the-agent-hud-spectator-v2.md +58 -0
- package/dist/packages/mcp/assets/kb/docs/docs-spectator-the-brain-view-and-the-pnl-chip.md +46 -0
- package/dist/packages/mcp/assets/kb/docs/docs-spectator-the-three-surfaces.md +1 -1
- package/dist/packages/mcp/assets/kb/docs/docs-spectator.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 +5 -2
- package/dist/packages/mcp/src/server.js +285 -36
- package/dist/packages/mcp/src/spectator-sink.js +85 -0
- package/dist/packages/packs/src/backtest.js +3 -1
- package/dist/packages/packs/src/index.js +1 -0
- package/dist/packages/packs/src/larp-score-backtest.js +119 -0
- package/dist/packages/popup/src/pages/chart-lib.js +169 -35
- package/dist/packages/popup/src/pages/chart.css +18 -0
- package/dist/packages/popup/src/pages/chart.html +6 -1
- package/dist/packages/popup/src/pages/chart.js +136 -10
- package/dist/packages/popup/src/pages/spectator.css +45 -0
- package/dist/packages/popup/src/pages/spectator.html +1 -0
- package/dist/packages/popup/src/pages/spectator.js +69 -0
- package/dist/packages/popup/src/protocol.js +4 -0
- package/dist/packages/popup/src/server.js +9 -1
- package/dist/packages/recorder/src/dev-history.js +7 -3
- 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/canvas.js +7 -0
- package/dist/packages/tui/src/fmt.js +53 -0
- package/dist/packages/tui/src/index.js +1 -0
- package/dist/packages/tui/src/keymap.js +25 -1
- package/dist/packages/tui/src/markers.js +219 -0
- package/dist/packages/tui/src/widgets.js +158 -6
- 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
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// screen and the token ANALYST panel. Cyberspace styling: the verdict and the tool-call lines are
|
|
3
3
|
// coral, the answer decrypts in through code glyphs, and a cost/latency footer sits on the caption.
|
|
4
4
|
import { Canvas, badge, spinnerGlyph, decryptText, wrap, mix, fmtUsd, fmtPrice, fmtPctDir, } from '../../../tui/src/index.js';
|
|
5
|
+
import { drawLarpGauge } from "../analyst/larp-gauge.js";
|
|
5
6
|
const verdictColor = (c, v) => {
|
|
6
7
|
const t = c.theme;
|
|
7
8
|
if (v === 'WATCH')
|
|
@@ -19,7 +20,7 @@ export function renderAnalystSession(c, x, y, w, h, s, opts) {
|
|
|
19
20
|
// Narrow panels (token screen) drop the model so cost · latency · tools still fits beside the title.
|
|
20
21
|
const full = s.status === 'error' ? 'analyst unavailable' : s.footer;
|
|
21
22
|
// 0.1.5: a codex conversation says so in the title; claude panels keep the original default.
|
|
22
|
-
const title = opts.title ?? (s.engine === 'codex' ? '✦ ANALYST · codex' : '✦ ANALYST · claude');
|
|
23
|
+
const title = opts.title ?? (s.engine === 'codex' ? '✦ ANALYST · codex' : s.engine === 'ollama' ? '✦ ANALYST · ollama' : '✦ ANALYST · claude');
|
|
23
24
|
const caption = title.length + full.length + 10 <= w ? full : full.split(' · ').slice(0, 3).join(' · ');
|
|
24
25
|
const capFg = s.status === 'error' ? t.warn : t.dim;
|
|
25
26
|
const box = c.box(x, y, w, h, { title, titleFg: t.ai, caption, captionFg: capFg, border: bc });
|
|
@@ -126,6 +127,9 @@ export function renderAnalystSession(c, x, y, w, h, s, opts) {
|
|
|
126
127
|
c.textR(box.x + 1, cy, inner - 1, right, { fg: t.muted, bg: mix(bg, vc, 0.18) });
|
|
127
128
|
cy += 1;
|
|
128
129
|
}
|
|
130
|
+
// task-1471: the LARP score gauge (from the MCP larp_check result, not the model), under the verdict.
|
|
131
|
+
if (s.larpGauge && cy < inputY - 1)
|
|
132
|
+
cy = drawLarpGauge(c, box.x + 2, cy, inner - 2, inputY - 1, s.larpGauge, bg);
|
|
129
133
|
// task-1313 trading view: the directional bias + setup quality, drawn under the risk verdict.
|
|
130
134
|
if (s.bias && cy < inputY - 1) {
|
|
131
135
|
const bc2 = s.bias === 'long' ? t.up : s.bias === 'short' || s.bias === 'avoid' ? t.down : t.warn;
|
|
@@ -179,7 +183,7 @@ export function renderAnalystSession(c, x, y, w, h, s, opts) {
|
|
|
179
183
|
// mcap/age + the analyst's one-line reason), navigable with ↑↓ and ⏎-to-jump. The numbers come from
|
|
180
184
|
// live data (resolved by the caller from the app's data layer, never from the model's text).
|
|
181
185
|
if (opts.results?.length && cy < inputY - 1) {
|
|
182
|
-
cy = renderResultsTable(c, box, bg, cy, inputY, inner, opts.results, opts.resultsCursor ?? 0, opts.resultsActive ?? false);
|
|
186
|
+
cy = renderResultsTable(c, box, bg, cy, inputY, inner, opts.results, opts.resultsCursor ?? 0, opts.resultsActive ?? false, opts.priceMode !== 'price');
|
|
183
187
|
}
|
|
184
188
|
if (s.candidates.length && cy < inputY - 1) {
|
|
185
189
|
cy += 1;
|
|
@@ -247,14 +251,17 @@ function fmtAge(min) {
|
|
|
247
251
|
* so it stays legible instead of wrapping into prose. The highlighted row (cursor) is tinted; when the
|
|
248
252
|
* table is active a `▸` marks it and the footer hint changes. Returns the new y.
|
|
249
253
|
*/
|
|
250
|
-
function renderResultsTable(c, box, bg, startY, inputY, inner, rows, cursor, active) {
|
|
254
|
+
function renderResultsTable(c, box, bg, startY, inputY, inner, rows, cursor, active, mcapFirst = true) {
|
|
251
255
|
const t = c.theme;
|
|
252
256
|
let cy = startY + 1;
|
|
253
257
|
if (cy >= inputY - 1)
|
|
254
258
|
return cy;
|
|
255
259
|
// Column plan: [symbol, price, 24h, liq, vol, mcap, age] then the reason fills the rest. Drop from
|
|
256
260
|
// the right as width shrinks so a narrow panel still shows symbol + price + change + a reason.
|
|
257
|
-
|
|
261
|
+
// task-1537: in the market-cap basis MCAP takes PRICE's slot (the headline number) and PRICE moves to MCAP's
|
|
262
|
+
const full = mcapFirst
|
|
263
|
+
? [['SYMBOL', 10], ['MCAP', 9], ['24H', 8], ['LIQ', 8], ['VOL', 8], ['PRICE', 8], ['AGE', 5]]
|
|
264
|
+
: [['SYMBOL', 10], ['PRICE', 9], ['24H', 8], ['LIQ', 8], ['VOL', 8], ['MCAP', 8], ['AGE', 5]];
|
|
258
265
|
let cols = full.slice();
|
|
259
266
|
// keep trimming trailing columns until the header + a minimal reason (12) fits
|
|
260
267
|
while (cols.length > 3 && cols.reduce((a, [, w]) => a + w + 1, 0) + 12 > inner - 2)
|
|
@@ -6,6 +6,7 @@ import { Canvas, sparkline, heatPct, decryptText, spinnerGlyph, fmtUsd, fmtPrice
|
|
|
6
6
|
import { headerModel } from "../state.js";
|
|
7
7
|
import { screenerView } from "../screener/view.js";
|
|
8
8
|
import { renderAnalystSession } from "./analyst-session.js";
|
|
9
|
+
import { priceModeOf } from "../display.js";
|
|
9
10
|
import { resolveAnalystResults } from "../analyst/results.js";
|
|
10
11
|
export function renderAnalyst(c, state) {
|
|
11
12
|
const t = c.theme;
|
|
@@ -28,7 +29,7 @@ export function renderAnalyst(c, state) {
|
|
|
28
29
|
frame: state.vfx.frame, code: state.vfx.code, calm: isCalm(state.vfx),
|
|
29
30
|
input: state.aiInput ?? '', inputFocused: focused,
|
|
30
31
|
scroll: state.aiScroll, revealAll: state.aiRevealAll,
|
|
31
|
-
results, resultsCursor: state.analyst.resultsCursor, resultsActive,
|
|
32
|
+
results, resultsCursor: state.analyst.resultsCursor, resultsActive, priceMode: priceModeOf(state), // task-1537
|
|
32
33
|
inputHint: focused ? 'type your question… ⏎ send · esc blur · analysis not advice'
|
|
33
34
|
: results.length ? 'i ask · ↑↓ pick coin · ⏎ open · o ticket · esc back'
|
|
34
35
|
: 'i ask · ⏎ focus · ↑↓ pick coin · PgUp/Dn scroll',
|
|
@@ -43,7 +44,7 @@ export function renderAnalyst(c, state) {
|
|
|
43
44
|
if (state.screener.source !== 'fixtures') {
|
|
44
45
|
const live = state.aiFocused === true;
|
|
45
46
|
const eng = state.analystEngine ?? 'claude'; // 0.1.5: the user's own CLI that will answer (claude | codex)
|
|
46
|
-
const b = c.box(0, top, chatW, bottom - top, { title: `✦ ANALYST · ${eng}`, titleFg: t.ai, caption: `read-only · local ${eng} CLI · on demand`, captionFg: t.dim, border: bc });
|
|
47
|
+
const b = c.box(0, top, chatW, bottom - top, { title: `✦ ANALYST · ${eng}`, titleFg: t.ai, caption: `read-only · local ${eng === 'ollama' ? 'ollama model' : `${eng} CLI`} · on demand`, captionFg: t.dim, border: bc });
|
|
47
48
|
const bbg = b.bg;
|
|
48
49
|
const bin = b.w - 2;
|
|
49
50
|
let by = b.y + 1;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
// dexterm — the AUTOTRADE screen's key handling (`Q`, task-1508). The loop calls autotradeKey() first while the
|
|
2
|
+
// screen captures typed keys (an id / file line, a field value, the flatten confirm), and autotradeAction() for
|
|
3
|
+
// every resolved action while the screen is open. Both only change this screen's state and the user's own
|
|
4
|
+
// strategy files; nothing here reaches a wallet, a key, a mandate or the signer.
|
|
5
|
+
import { INPUT_MAX, backtestSubject, beginFieldEdit, beginImport, beginNew, commitInput, commitTyping, confirmKey, exportSelected, nextView, openEditor, reloadList, refreshRunner, revalidateTyping, runnerVerb, saveEditor, selectedEntry, startBacktest, startCompareBacktest, startSweep, toggleMark, undoEditor, } from "./autotrade-ui.js";
|
|
6
|
+
import { openReview, reviewKey } from "./autotrade-proposals.js";
|
|
7
|
+
const PRINTABLE = (k) => (k.name === 'space' ? ' ' : k.name === 'char' && k.ch && !k.ctrl && !k.alt && !/[\u0000-\u001f\u007f]/.test(k.ch) ? k.ch : null);
|
|
8
|
+
/** A captured key (input line, field value or confirm). Returns true when the key was consumed. */
|
|
9
|
+
export function autotradeKey(ui, key) {
|
|
10
|
+
// task-1507: a chat proposal's review card owns the keyboard (y applies, a LOOSER edit needs a second y, n dismisses)
|
|
11
|
+
if (ui.review) {
|
|
12
|
+
ui.notice = reviewKey(ui, key);
|
|
13
|
+
if (!ui.review)
|
|
14
|
+
reloadList(ui);
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
if (ui.confirm) {
|
|
18
|
+
ui.notice = confirmKey(ui, key.name === 'char' && key.ch === 'y' && !key.ctrl && !key.alt);
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
if (ui.input) {
|
|
22
|
+
const inp = ui.input;
|
|
23
|
+
if (key.name === 'esc') {
|
|
24
|
+
ui.input = null;
|
|
25
|
+
ui.notice = null;
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
if (key.name === 'enter') {
|
|
29
|
+
ui.notice = commitInput(ui);
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
if (key.name === 'backspace') {
|
|
33
|
+
inp.text = inp.text.slice(0, -1);
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
if (key.ctrl && key.ch === 'u') {
|
|
37
|
+
inp.text = '';
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
const ch = PRINTABLE(key);
|
|
41
|
+
// an id is lowercase letters, digits and dashes only, so it can never carry a path
|
|
42
|
+
if (ch && (inp.kind === 'import' ? inp.text.length < INPUT_MAX : /^[a-z0-9-]$/.test(ch) && inp.text.length < 32))
|
|
43
|
+
inp.text += ch;
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
const ty = ui.view === 'editor' ? ui.editor?.typing : null;
|
|
47
|
+
if (ty) {
|
|
48
|
+
if (key.name === 'esc') {
|
|
49
|
+
ui.editor.typing = null;
|
|
50
|
+
ui.notice = null;
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
if (key.name === 'enter') {
|
|
54
|
+
ui.notice = commitTyping(ui);
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
if (key.name === 'backspace')
|
|
58
|
+
ty.text = ty.text.slice(0, -1);
|
|
59
|
+
else if (key.ctrl && key.ch === 'u')
|
|
60
|
+
ty.text = '';
|
|
61
|
+
else {
|
|
62
|
+
const ch = PRINTABLE(key);
|
|
63
|
+
if (ch && ty.text.length < INPUT_MAX)
|
|
64
|
+
ty.text += ch;
|
|
65
|
+
else
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
revalidateTyping(ui);
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
function move(ui, delta) {
|
|
74
|
+
if (ui.view === 'list')
|
|
75
|
+
ui.selected = Math.max(0, Math.min(ui.entries.length - 1, ui.selected + delta));
|
|
76
|
+
else if (ui.view === 'editor' && ui.editor)
|
|
77
|
+
ui.editor.selected = Math.max(0, Math.min(ui.editor.fields.length - 1, ui.editor.selected + delta));
|
|
78
|
+
else if (ui.view === 'compare' && ui.compare)
|
|
79
|
+
ui.compare.scroll = Math.max(0, ui.compare.scroll + delta);
|
|
80
|
+
}
|
|
81
|
+
const PAGE = 10;
|
|
82
|
+
/**
|
|
83
|
+
* One resolved action on the AUTOTRADE screen. Returns true when it was handled here (the loop then does
|
|
84
|
+
* nothing else with it); false lets the loop's own handling run (esc on the list pops the screen stack, `q`
|
|
85
|
+
* quits, the global screen keys still navigate away).
|
|
86
|
+
*/
|
|
87
|
+
export function autotradeAction(ui, action) {
|
|
88
|
+
const say = (s) => { ui.notice = s ?? null; return true; };
|
|
89
|
+
const e = selectedEntry(ui);
|
|
90
|
+
switch (action) {
|
|
91
|
+
case 'move.down':
|
|
92
|
+
move(ui, 1);
|
|
93
|
+
return true;
|
|
94
|
+
case 'move.up':
|
|
95
|
+
move(ui, -1);
|
|
96
|
+
return true;
|
|
97
|
+
case 'move.pagedown':
|
|
98
|
+
move(ui, PAGE);
|
|
99
|
+
return true;
|
|
100
|
+
case 'move.pageup':
|
|
101
|
+
move(ui, -PAGE);
|
|
102
|
+
return true;
|
|
103
|
+
case 'move.top':
|
|
104
|
+
move(ui, -1e9);
|
|
105
|
+
return true;
|
|
106
|
+
case 'move.bottom':
|
|
107
|
+
move(ui, 1e9);
|
|
108
|
+
return true;
|
|
109
|
+
case 'back':
|
|
110
|
+
if (ui.view === 'list')
|
|
111
|
+
return false;
|
|
112
|
+
ui.view = 'list';
|
|
113
|
+
return say(null);
|
|
114
|
+
case 'autotrade.view':
|
|
115
|
+
nextView(ui);
|
|
116
|
+
if (ui.view === 'runner')
|
|
117
|
+
refreshRunner(ui);
|
|
118
|
+
return say(null);
|
|
119
|
+
case 'open':
|
|
120
|
+
case 'autotrade.edit':
|
|
121
|
+
if (ui.view === 'editor')
|
|
122
|
+
return say(beginFieldEdit(ui));
|
|
123
|
+
if (ui.view !== 'list')
|
|
124
|
+
return action === 'open' ? true : say('e edits from the strategies list');
|
|
125
|
+
return say(e ? openEditor(ui, e.id) : 'no strategy selected');
|
|
126
|
+
case 'autotrade.new': return say(ui.view === 'list' ? beginNew(ui, false) : 'n works on the strategies list (esc)');
|
|
127
|
+
case 'autotrade.dup': return say(ui.view === 'list' ? beginNew(ui, true) : 'd works on the strategies list (esc)');
|
|
128
|
+
case 'autotrade.import':
|
|
129
|
+
if (ui.view !== 'list')
|
|
130
|
+
return say('i works on the strategies list (esc)');
|
|
131
|
+
beginImport(ui);
|
|
132
|
+
return say(null);
|
|
133
|
+
case 'autotrade.export': return say(ui.view === 'list' ? exportSelected(ui) : 'x works on the strategies list (esc)');
|
|
134
|
+
case 'autotrade.compare': return say(ui.view === 'list' ? toggleMark(ui) : 'c marks strategies on the list (esc)');
|
|
135
|
+
case 'autotrade.save': return say(ui.view === 'editor' ? saveEditor(ui) : 's saves in the editor');
|
|
136
|
+
case 'autotrade.undo': return say(ui.view === 'editor' ? undoEditor(ui) : 'u undoes in the editor');
|
|
137
|
+
case 'autotrade.backtest': {
|
|
138
|
+
if (ui.view === 'compare')
|
|
139
|
+
return say(startCompareBacktest(ui));
|
|
140
|
+
if (ui.view === 'editor' && ui.editor)
|
|
141
|
+
return say(`${startBacktest(ui, ui.editor.id)}${ui.editor.edits.length ? ' (the saved version; s saves your edits first)' : ''}`);
|
|
142
|
+
if (ui.view === 'backtest') {
|
|
143
|
+
const s = backtestSubject(ui);
|
|
144
|
+
return say(s ? startBacktest(ui, s.id) : 'no strategy selected');
|
|
145
|
+
}
|
|
146
|
+
return say(e ? startBacktest(ui, e.id) : 'no strategy selected');
|
|
147
|
+
}
|
|
148
|
+
case 'autotrade.sweep': {
|
|
149
|
+
const id = ui.view === 'editor' && ui.editor ? ui.editor.id : ui.view === 'backtest' ? backtestSubject(ui)?.id : e?.id;
|
|
150
|
+
return say(id ? startSweep(ui, id) : 'no strategy selected');
|
|
151
|
+
}
|
|
152
|
+
case 'autotrade.proposal': return say(ui.view === 'list' ? openReview(ui) || null : 'o reviews chat proposals on the strategies list (esc)');
|
|
153
|
+
case 'autotrade.run':
|
|
154
|
+
ui.view = 'runner';
|
|
155
|
+
refreshRunner(ui);
|
|
156
|
+
reloadList(ui);
|
|
157
|
+
return say('starting and stopping a paper run ships with the runner (not in this build yet) · this view shows a runner as soon as one writes its status file');
|
|
158
|
+
case 'autotrade.kill':
|
|
159
|
+
refreshRunner(ui);
|
|
160
|
+
return say(runnerVerb(ui, 'kill'));
|
|
161
|
+
case 'autotrade.pause':
|
|
162
|
+
refreshRunner(ui);
|
|
163
|
+
return say(runnerVerb(ui, 'pause'));
|
|
164
|
+
case 'autotrade.flatten':
|
|
165
|
+
refreshRunner(ui);
|
|
166
|
+
return say(runnerVerb(ui, 'flatten'));
|
|
167
|
+
default: return false;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// dexterm — chat proposals on the AUTOTRADE screen (task-1507 AT-5, AUTOTRADE-SPEC §2a). PAPER ONLY.
|
|
2
|
+
//
|
|
3
|
+
// The analyst (or any MCP agent) can only PROPOSE a strategy edit: `strategy_propose_edit/new` write a proposal file
|
|
4
|
+
// and nothing else. This module is the ONLY path that applies one, and it runs only on the user's physical keys:
|
|
5
|
+
//
|
|
6
|
+
// o on the strategies list opens the diff card of the newest pending proposal (the selected strategy's first)
|
|
7
|
+
// y applies a tighter or neutral edit
|
|
8
|
+
// y on a LOOSER edit opens the "less safe" popup (every less-safe field named) and a SECOND y applies it
|
|
9
|
+
// n dismisses the proposal · esc (or any other key) closes the card and leaves it pending
|
|
10
|
+
//
|
|
11
|
+
// Applying re-checks everything from scratch (`checkProposal`: the base hash, the model deny-list on the result,
|
|
12
|
+
// the validator and a fresh risk delta: the stored riskDelta is never trusted), then writes through StrategyStore
|
|
13
|
+
// (a new version, one `.journal.jsonl` line naming the proposer, the proposal id, the ops and both hashes).
|
|
14
|
+
// The key loop feeds `reviewKey` decoded keyboard keys only; no voice, pipe or agent path reaches it.
|
|
15
|
+
import { applyOps, dextermHome } from '../../../custom/src/index.js';
|
|
16
|
+
import * as engine from '../../../autotrade/src/index.js';
|
|
17
|
+
import { ProposalFiles, checkProposal, proposalCardView } from '../../../mcp/src/index.js';
|
|
18
|
+
const ENGINE = { at: engine, applyOps };
|
|
19
|
+
/** Pending proposals as display cards, re-read at most once a second (the list view asks every frame). */
|
|
20
|
+
export function proposalSource(files, now = Date.now) {
|
|
21
|
+
let at = -Infinity;
|
|
22
|
+
let recs = [];
|
|
23
|
+
const pending = () => {
|
|
24
|
+
const t = now();
|
|
25
|
+
if (t - at >= 1000) {
|
|
26
|
+
try {
|
|
27
|
+
recs = files.list({ status: 'pending' });
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
recs = [];
|
|
31
|
+
}
|
|
32
|
+
at = t;
|
|
33
|
+
}
|
|
34
|
+
return recs;
|
|
35
|
+
};
|
|
36
|
+
return { pending, cards: () => pending().map(proposalCardView), invalidate: () => { at = -Infinity; } };
|
|
37
|
+
}
|
|
38
|
+
export const proposalFilesFor = (env = process.env) => new ProposalFiles(dextermHome(env));
|
|
39
|
+
const inputOf = (r) => ({ kind: r.kind, id: r.id, ops: r.ops, from: r.from, name: r.name, why: r.why });
|
|
40
|
+
/** Re-check a stored proposal against the strategy as it is NOW (stale when the strategy changed since). */
|
|
41
|
+
export function recheck(store, rec) {
|
|
42
|
+
const c = checkProposal(ENGINE, store, inputOf(rec));
|
|
43
|
+
if (c.ok && c.before.hash !== rec.beforeHash) {
|
|
44
|
+
return { ok: false, stage: 'input', errors: [{ path: `/${rec.id}`, msg: `${rec.id} changed since this proposal (it was made on ${rec.beforeHash}, it is ${c.before.hash} now): dismiss it with n and ask again` }], warnings: [] };
|
|
45
|
+
}
|
|
46
|
+
return c;
|
|
47
|
+
}
|
|
48
|
+
/** The keys a proposal needs: one for a tighter or neutral edit, two (the less-safe popup) for a looser one. */
|
|
49
|
+
export const keysNeeded = (c) => (c.ok && c.riskDelta === 'looser' ? 2 : 1);
|
|
50
|
+
/**
|
|
51
|
+
* Apply a proposal. `keys` must be the physical keys the user pressed on its card (`reviewKey` collects them);
|
|
52
|
+
* a looser edit needs two. Returns the toast line. Nothing else in the app calls the store with a proposal id.
|
|
53
|
+
*/
|
|
54
|
+
export function applyProposal(store, files, rec, keys, now = Date.now()) {
|
|
55
|
+
if (rec.status !== 'pending')
|
|
56
|
+
return { ok: false, message: `proposal ${rec.proposalId} is already ${rec.status}` };
|
|
57
|
+
const c = recheck(store, rec);
|
|
58
|
+
if (!c.ok)
|
|
59
|
+
return { ok: false, message: `not applied: ${c.errors.map(engine.fmtIssue).join('; ')}` };
|
|
60
|
+
const yes = keys.filter((k) => k === 'y').length;
|
|
61
|
+
const need = keysNeeded(c);
|
|
62
|
+
if (yes < need)
|
|
63
|
+
return { ok: false, message: `not applied: a LOOSER edit needs a second keypress (${yes} of ${need})` };
|
|
64
|
+
const why = `${rec.why} · applied by keypress${need === 2 ? ' after the less-safe popup' : ''}`.slice(0, 300);
|
|
65
|
+
const w = rec.kind === 'edit'
|
|
66
|
+
? store.patch(rec.id, c.effectiveOps, { actor: rec.actor, why, proposalId: rec.proposalId })
|
|
67
|
+
: store.create(c.afterRaw, { actor: rec.actor, why, from: rec.from, proposalId: rec.proposalId });
|
|
68
|
+
if (!w.ok)
|
|
69
|
+
return { ok: false, message: `not applied: ${w.errors.map(engine.fmtIssue).join('; ')}` };
|
|
70
|
+
if (w.strategy.hash !== c.after.hash)
|
|
71
|
+
return { ok: false, message: `applied, but the stored hash ${w.strategy.hash} differs from the proposal's ${c.after.hash}: check the journal` };
|
|
72
|
+
files.resolve(rec.proposalId, 'applied', { appliedVersion: w.strategy.version, keys: [...keys] }, now);
|
|
73
|
+
return { ok: true, message: `${rec.kind === 'new' ? 'created' : 'applied'} ${rec.id} v${w.strategy.version} (${c.riskDelta}) · journaled with ${rec.proposalId}` };
|
|
74
|
+
}
|
|
75
|
+
// ───────────────────────────── the card's keys (AutotradeUi) ─────────────────────────────
|
|
76
|
+
/** `o`: open the newest pending proposal (the selected strategy's first). Returns the notice. */
|
|
77
|
+
export function openReview(ui) {
|
|
78
|
+
const src = ui.deps.proposalSource;
|
|
79
|
+
if (!src)
|
|
80
|
+
return 'chat proposals are not available on this run';
|
|
81
|
+
src.invalidate();
|
|
82
|
+
const pending = src.pending();
|
|
83
|
+
if (!pending.length)
|
|
84
|
+
return 'no chat proposals · ask the analyst (a) to change a strategy; its diff card shows up here';
|
|
85
|
+
const sel = ui.entries[ui.selected]?.id;
|
|
86
|
+
const rec = pending.find((p) => p.id === sel) ?? pending[0];
|
|
87
|
+
ui.review = { rec, check: recheck(ui.deps.store, rec), stage: 'card', keys: [] };
|
|
88
|
+
return '';
|
|
89
|
+
}
|
|
90
|
+
/** A key while the card is open. Returns the notice (null keeps the card's own text). */
|
|
91
|
+
export function reviewKey(ui, key) {
|
|
92
|
+
const rv = ui.review;
|
|
93
|
+
if (!rv)
|
|
94
|
+
return null;
|
|
95
|
+
const ch = key.name === 'char' && !key.ctrl && !key.alt ? key.ch : null;
|
|
96
|
+
const src = ui.deps.proposalSource;
|
|
97
|
+
const files = ui.deps.proposalFiles;
|
|
98
|
+
if (ch === 'n' && files) {
|
|
99
|
+
files.resolve(rv.rec.proposalId, 'dismissed', {}, ui.deps.now());
|
|
100
|
+
ui.review = null;
|
|
101
|
+
src?.invalidate();
|
|
102
|
+
return `dismissed ${rv.rec.proposalId} (${rv.rec.id} unchanged)`;
|
|
103
|
+
}
|
|
104
|
+
if (ch !== 'y') {
|
|
105
|
+
ui.review = null;
|
|
106
|
+
return 'proposal left pending (o reopens it)';
|
|
107
|
+
}
|
|
108
|
+
if (!rv.check.ok)
|
|
109
|
+
return `cannot apply: ${rv.check.errors.map(engine.fmtIssue).join('; ')} · n dismisses it`;
|
|
110
|
+
rv.keys.push('y');
|
|
111
|
+
if (rv.check.riskDelta === 'looser' && rv.stage === 'card') {
|
|
112
|
+
rv.stage = 'less-safe';
|
|
113
|
+
return 'LESS SAFE: y again applies it · any other key cancels';
|
|
114
|
+
}
|
|
115
|
+
if (!files) {
|
|
116
|
+
ui.review = null;
|
|
117
|
+
return 'chat proposals are not available on this run';
|
|
118
|
+
}
|
|
119
|
+
const r = applyProposal(ui.deps.store, files, rv.rec, rv.keys, ui.deps.now());
|
|
120
|
+
ui.review = null;
|
|
121
|
+
src?.invalidate();
|
|
122
|
+
return r.message;
|
|
123
|
+
}
|