methodalgo-cli 1.0.1

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.
@@ -0,0 +1,204 @@
1
+ import chalk from "chalk";
2
+ import config from "./config-manager.js";
3
+
4
+ const translations = {
5
+ en: {
6
+ HELP_DESC: "Methodalgo Market Intelligence Tool (Optimized for LLMs)",
7
+ CONFIG_DESC: "Manage tool configuration (e.g., API Key)",
8
+ CONFIG_SET_DESC: "Set configuration item",
9
+ CONFIG_GET_DESC: "Get configuration item",
10
+ CONFIG_LIST_DESC: "List all configurations (excluding sensitive info)",
11
+ SNAPSHOT_DESC: "Get TradingView chart snapshot",
12
+ NEWS_DESC: "Get cryptocurrency market news",
13
+ SIGNALS_DESC: "Get trading signals",
14
+ DASHBOARD_DESC: "Open real-time TUI dashboard (3-column layout)",
15
+ COL_NEWS: "Market News",
16
+ COL_SIGNALS: "L2 Signals",
17
+ COL_STATUS: "System Status",
18
+ TYPE_ARTICLE: "Articles",
19
+ TYPE_NEWS: "Breaking",
20
+ TYPE_ONCHAIN: "On-Chain",
21
+ TYPE_REPORT: "Reports",
22
+ LABEL_BREAKOUT: "Breakout",
23
+ LABEL_EXHAUSTION: "Exhaustion",
24
+ LABEL_GOLDEN_PIT: "Golden Pit",
25
+ LABEL_LIQUIDATION: "Liquidation",
26
+ LABEL_MARKET_TODAY: "Market Today",
27
+ LABEL_TOKEN_UNLOCK: "Token Unlock",
28
+ LABEL_FEAR_GREED: "Fear & Greed Index",
29
+ SENTIMENT_EXTREME_FEAR: "Extreme Fear",
30
+ SENTIMENT_FEAR: "Fear",
31
+ SENTIMENT_NEUTRAL: "Neutral",
32
+ SENTIMENT_GREED: "Greed",
33
+ SENTIMENT_EXTREME_GREED: "Extreme Greed",
34
+ GOLDEN_PIT_BULL: "Bull golden Pit",
35
+ GOLDEN_PIT_BEAR: "Bear golden Pit",
36
+ BREAKOUT_UP: "Breakup",
37
+ BREAKOUT_DOWN: "Breakdown",
38
+ LIQUIDATION_LONG: "LONG Liquidation",
39
+ LIQUIDATION_SHORT: "SHORT Liquidation",
40
+ TUI_QUIT: "Press 'q' or 'Ctrl+C' to quit",
41
+ ERR_MISSING_KEY: "Missing API Key. Please run 'methodalgo config set api-key <your-key>'",
42
+ ERR_NETWORK: "Network error",
43
+ SUGGESTION_KEY: "Please check your network connection or API Key configuration.",
44
+ SET_SUCCESS: "Set {key} to {value}",
45
+ VAL_NOT_SET: "Configuration {key} is not set",
46
+ FETCH_SUCCESS: "Fetched {count} items:",
47
+ SNAPSHOT_SUCCESS: "Snapshot fetched successfully [{ticker} {tf}]:",
48
+ INVALID_CMD: "Invalid command: {cmd}\nUse 'methodalgo --help' for available commands.",
49
+ LABEL_SUGGESTION: "Suggestion: ",
50
+ LABEL_EXAMPLE: "Example: ",
51
+ SIGNALS_CHANNELS: `Supported Channels:
52
+ ${chalk.cyan("- breakout-htf")}: ${chalk.gray("Detects 1D/3D trends. Alerts on breaking high/low within a 100-candle rolling window.")}
53
+ ${chalk.cyan("- breakout-mtf")}: ${chalk.gray("Detects 1H/4H trends. Alerts on breaking high/low within a 100-candle rolling window.")}
54
+ ${chalk.cyan("- breakout-24h")}: ${chalk.gray("Continuous breakout detection based on a 24-hour rolling window of high/low prices.")}
55
+ ${chalk.cyan("- liquidation")}: ${chalk.gray("Large liquidation order alerts.")}
56
+ ${chalk.cyan("- exhaustion-seller")}: ${chalk.gray("Reversal signals (Sellers exhausted, price likely to rise), based on Grim Reaper Heatmap.")}
57
+ ${chalk.cyan("- exhaustion-buyer")}: ${chalk.gray("Reversal signals (Buyers exhausted, price likely to fall), based on Grim Reaper Heatmap.")}
58
+ ${chalk.cyan("- golden-pit-mtf")}: ${chalk.gray("'Smart Cloud' patterns (Pump/Dump), 30m/1h/4h timeframes. Bull Pit: rise after pullback, Bear Pit: fall after rally.")}
59
+ ${chalk.cyan("- golden-pit-ltf")}: ${chalk.gray("'Smart Cloud' patterns (Pump/Dump), 5m/15m timeframes. Bull Pit: rise after pullback, Bear Pit: fall after rally.")}
60
+ ${chalk.cyan("- token-unlock")}: ${chalk.gray("Token unlock event highlights with countdowns.")}
61
+ ${chalk.cyan("- etf-tracker")}: ${chalk.gray("Daily inflows/outflows for BTC/ETH and SOL/XRP.")}
62
+ ${chalk.cyan("- market-today")}: ${chalk.gray("Alt Season Index and Fear & Greed Index.")}`,
63
+ NEWS_TYPES: `Supported Types:
64
+ ${chalk.cyan("- article")}: ${chalk.gray("Market news & analysis.")}
65
+ ${chalk.cyan("- breaking")}: ${chalk.gray("Real-time breaking news.")}
66
+ ${chalk.cyan("- onchain")}: ${chalk.gray("On-chain abnormality detection.")}
67
+ ${chalk.cyan("- report")}: ${chalk.gray("Institutional research reports.")}`,
68
+ ERR_AUTH_FAILED: "API Key Invalid or Expired.",
69
+ GET_API_KEY_LINK: "Get a new key at: https://account.methodalgo.com/account/api-keys",
70
+ RECONFIG_TIP: "Use 'methodalgo config set api-key <key>' to update.",
71
+ ONBOARD_WELCOME: "Welcome to MethodAlgo! It seems you haven't set an API Key yet.",
72
+ ONBOARD_PROMPT: "Please enter your API Key: ",
73
+ ONBOARD_VALIDATING: "Validating API Key... (Testing with a small request)",
74
+ ONBOARD_SUCCESS: "API Key verified and saved successfully!",
75
+ ONBOARD_FAILED: "Invalid API Key. Please double check and try again.",
76
+ ONBOARD_GET_LINK: "Get your key here: https://account.methodalgo.com/account/api-keys",
77
+ ONBOARD_LANG_PROMPT: "Select Language (1: English, 2: 中文): ",
78
+ LOGOUT_DESC: "Logout and clear API Key",
79
+ LOGOUT_SUCCESS: "Successfully logged out. API Key cleared, language preference kept.",
80
+ ERR_INVALID_CONFIG_KEY: "Invalid configuration key: {key}",
81
+ VAL_ALLOWED_KEYS: "Allowed keys are: api-key, lang, api-base",
82
+ ARG_SYMBOL_DESC: "Symbol (e.g., SOLUSDT for Spot, SOLUSDT.P for Perpetual)",
83
+ ARG_TF_DESC: "Timeframe (default 60)",
84
+ OPT_URL_DESC: "Force return the URL instead of binary (recommended for LLMs)",
85
+ OPT_BUFFER_DESC: "Force return binary buffer and try to render in terminal",
86
+ OPT_SEARCH_DESC: "Search keywords in news titles",
87
+ OPT_START_DATE_DESC: "Filter news from this date (ISO 8601 or YYYY-MM-DD, e.g., 2026-03-20)",
88
+ OPT_END_DATE_DESC: "Filter news up to this date (ISO 8601 or YYYY-MM-DD)",
89
+ SNAPSHOT_EXAMPLE: "methodalgo snapshot BTCUSDT 30",
90
+ NEWS_EXAMPLE: "methodalgo news --type breaking --limit 5 --search 'Bitcoin'",
91
+ SIGNALS_EXAMPLE: "methodalgo signals breakout-mtf",
92
+ CONFIG_EXAMPLE: "methodalgo config set lang zh",
93
+ DASHBOARD_EXAMPLE: "methodalgo dashboard",
94
+ TUI_HINTS: "Q:Quit | Tab:Switch | Enter:Detail",
95
+ OPT_LIMIT_DESC: "Limit results (max 600, or 100 with --after)",
96
+ OPT_AFTER_DESC: "Message ID to fetch signals after (for incremental fetching)",
97
+ SIGNALS_LIMIT_NOTE: "Note: Limit up to 600 if 'after' is not used, 100 if used.",
98
+ NEWS_LIMIT_NOTE: "Note: News data is from DB, max 500 per request."
99
+ },
100
+ zh: {
101
+ HELP_DESC: "Methodalgo 市场情报工具 (针对大模型优化版)",
102
+ CONFIG_DESC: "管理工具配置 (如 API Key)",
103
+ CONFIG_SET_DESC: "设置配置项",
104
+ CONFIG_GET_DESC: "获取配置项",
105
+ CONFIG_LIST_DESC: "列出所有配置 (不包含敏感信息)",
106
+ SNAPSHOT_DESC: "获取 TradingView 图表快照",
107
+ NEWS_DESC: "获取加密货币市场新闻",
108
+ SIGNALS_DESC: "获取交易信号",
109
+ DASHBOARD_DESC: "打开实时 TUI 仪表盘 (三列布局)",
110
+ COL_NEWS: "市场新闻",
111
+ COL_SIGNALS: "L2 信号",
112
+ COL_STATUS: "系统状态",
113
+ TYPE_ARTICLE: "新闻",
114
+ TYPE_NEWS: "突发快讯",
115
+ TYPE_ONCHAIN: "链上监测",
116
+ TYPE_REPORT: "机构报告",
117
+ LABEL_BREAKOUT: "突破",
118
+ LABEL_EXHAUSTION: "死神清算",
119
+ LABEL_GOLDEN_PIT: "黄金坑",
120
+ LABEL_LIQUIDATION: "强平订单",
121
+ LABEL_MARKET_TODAY: "今日市场",
122
+ LABEL_TOKEN_UNLOCK: "代币解锁",
123
+ TUI_QUIT: "按 'q' 或 'Ctrl+C' 退出",
124
+ ERR_MISSING_KEY: "缺失 API Key。请运行 'methodalgo config set api-key <your-key>'",
125
+ ERR_NETWORK: "网络错误",
126
+ SUGGESTION_KEY: "请检查您的网络连接或 API Key 是否正确配置。",
127
+ SET_SUCCESS: "已设置 {key} 为 {value}",
128
+ VAL_NOT_SET: "配置项 {key} 未设置",
129
+ FETCH_SUCCESS: "获取到 {count} 条结果:",
130
+ SNAPSHOT_SUCCESS: "快照获取成功 [{ticker} {tf}]:",
131
+ INVALID_CMD: "无效的命令: {cmd}\n使用 'methodalgo --help' 查看可用命令。",
132
+ LABEL_SUGGESTION: "建议方案: ",
133
+ LABEL_EXAMPLE: "示例: ",
134
+ SIGNALS_CHANNELS: `支持的频道:
135
+ ${chalk.yellow("- breakout-htf")}: ${chalk.gray("检测1D/3D趋势。在当前K线在100根K线的浮动时间窗口中,突破期间最高/低点时的报警。")}
136
+ ${chalk.yellow("- breakout-mtf")}: ${chalk.gray("检测1H/4H趋势。在当前K线在100根K线的浮动时间窗口中,突破期间最高/低点时的报警。")}
137
+ ${chalk.yellow("- breakout-24h")}: ${chalk.gray("基于过去24小时滚动时间窗口的最高/低点的持续突破检测。")}
138
+ ${chalk.yellow("- liquidation")}: ${chalk.gray("大额强平订单实时提醒。")}
139
+ ${chalk.yellow("- exhaustion-seller")}: ${chalk.gray("基于死神清算热力图,单边卖家强平库存<10%与<5%的反转信号 (卖家耗尽,价格会上升)。")}
140
+ ${chalk.yellow("- exhaustion-buyer")}: ${chalk.gray("基于死神清算热力图,单边买家强平库存<10%与<5%的反转信号 (买家耗尽,价格会下降)。")}
141
+ ${chalk.yellow("- golden-pit-mtf")}: ${chalk.gray("'Smart Cloud' 模式,预示随后会有显著的程序化波动 (30m/1h/4h 周期)。Bull Pit 代表短暂回撤后价格会拉升,Bear Pit 代表短暂上扬后价格会继续下降。")}
142
+ ${chalk.yellow("- golden-pit-ltf")}: ${chalk.gray("'Smart Cloud' 模式,预示随后会有显著的程序化波动 (5m/15m 周期)。Bull Pit 代表短暂回撤后价格会拉升,Bear Pit 代表短暂上扬后价格会继续下降。")}
143
+ ${chalk.yellow("- token-unlock")}: ${chalk.gray("代币解锁事件高亮及倒计时计。")}
144
+ ${chalk.yellow("- etf-tracker")}: ${chalk.gray("BTC/ETH 和 SOL/XRP 每日资金流入/流出追踪。")}
145
+ ${chalk.yellow("- market-today")}: ${chalk.gray("每日山寨季指数与贪婪恐惧指数。")}`,
146
+ NEWS_TYPES: `支持的类型:
147
+ ${chalk.yellow("- article")}: ${chalk.gray("深度市场新闻与分析")}
148
+ ${chalk.yellow("- breaking")}: ${chalk.gray("实时快讯")}
149
+ ${chalk.yellow("- onchain")}: ${chalk.gray("链上数据异动监测")}
150
+ ${chalk.yellow("- report")}: ${chalk.gray("机构研究报告")}`,
151
+ ERR_AUTH_FAILED: "API Key 无效或已过期。",
152
+ GET_API_KEY_LINK: "请在此获取新 Key: https://account.methodalgo.com/zh/account/api-keys",
153
+ RECONFIG_TIP: "请运行 'methodalgo config set api-key <key>' 进行更新。",
154
+ ONBOARD_WELCOME: "欢迎使用 MethodAlgo!检测到您尚未配置 API Key。",
155
+ ONBOARD_PROMPT: "请输入您的 API Key: ",
156
+ ONBOARD_VALIDATING: "正在验证 API Key... (尝试拉取测试数据)",
157
+ ONBOARD_SUCCESS: "API Key 验证通过并已成功保存!",
158
+ ONBOARD_FAILED: "API Key 无效,请检查后重试。",
159
+ ONBOARD_GET_LINK: "获取链接: https://account.methodalgo.com/zh/account/api-keys",
160
+ ONBOARD_LANG_PROMPT: "请选择语言 / Select Language (1: English, 2: 中文): ",
161
+ LOGOUT_DESC: "退出登录并清除 API Key",
162
+ LOGOUT_SUCCESS: "成功退出登录。API Key 已清除,语言设置已保留。",
163
+ ERR_INVALID_CONFIG_KEY: "无效的配置键: {key}",
164
+ VAL_ALLOWED_KEYS: "允许的键包括: api-key, lang, api-base",
165
+ ARG_SYMBOL_DESC: "交易对符号 (例如: SOLUSDT 为现货, SOLUSDT.P 为合约)",
166
+ ARG_TF_DESC: "时间周期 (默认 60)",
167
+ OPT_URL_DESC: "强制返回 URL 链接而非二进制流 (大模型调用时建议开启)",
168
+ OPT_BUFFER_DESC: "强制返回二进制流并尝试在终端渲染",
169
+ OPT_SEARCH_DESC: "在新闻标题中搜索关键词",
170
+ OPT_START_DATE_DESC: "从此日期开始筛选 (支持 ISO 8601 或 YYYY-MM-DD,如: 2026-03-20)",
171
+ OPT_END_DATE_DESC: "在此日期前筛选 (支持 ISO 8601 或 YYYY-MM-DD)",
172
+ SNAPSHOT_EXAMPLE: "methodalgo snapshot BTCUSDT 30",
173
+ NEWS_EXAMPLE: "methodalgo news --type breaking --limit 5 --search '比特币'",
174
+ SIGNALS_EXAMPLE: "methodalgo signals breakout-mtf",
175
+ CONFIG_EXAMPLE: "methodalgo config set lang zh",
176
+ DASHBOARD_EXAMPLE: "methodalgo dashboard",
177
+ TUI_HINTS: "Q:退出 | Tab:切换 | Enter:详情",
178
+ OPT_LIMIT_DESC: "获取结果数量 (最高 600,使用 --after 时最高 100)",
179
+ OPT_AFTER_DESC: "起始消息 ID (用于增量抓取)",
180
+ SIGNALS_LIMIT_NOTE: "注:不使用 after 时 limit 最高 600,使用时最高 100。",
181
+ NEWS_LIMIT_NOTE: "注:新闻类数据读取自数据库,单次最高限额 500 条。"
182
+ }
183
+ };
184
+
185
+ export function getLang() {
186
+ return config.get("lang") || "en";
187
+ }
188
+
189
+ /**
190
+ * 翻译函数
191
+ * @param {string} key 键值
192
+ * @param {object} params 替换参数
193
+ */
194
+ export function t(key, params = {}) {
195
+ const lang = config.get("lang") || "en";
196
+ let text = translations[lang][key] || translations["en"][key] || key;
197
+
198
+ // 简单的占位符替换
199
+ Object.keys(params).forEach(p => {
200
+ text = text.replace(`{${p}}`, params[p]);
201
+ });
202
+
203
+ return text;
204
+ }
@@ -0,0 +1,27 @@
1
+ import chalk from "chalk";
2
+ import { t } from "./i18n.js";
3
+
4
+ /**
5
+ * 针对 LLM 优化的日志/错误输出工具
6
+ */
7
+ const logger = {
8
+ info: (msg) => console.log(chalk.blue("ℹ ") + msg),
9
+ success: (msg) => console.log(chalk.green("✔ ") + msg),
10
+ warn: (msg) => console.log(chalk.yellow("⚠ ") + msg),
11
+ error: (msg, suggestion) => {
12
+ console.error(chalk.red("✖ ") + chalk.bold(msg));
13
+ if (suggestion) {
14
+ console.error(chalk.cyan(`\n💡 ${t("LABEL_SUGGESTION")}`) + suggestion);
15
+ }
16
+ },
17
+ json: (data) => console.log(JSON.stringify(data, null, 2)),
18
+ isIterm2: process.env.TERM_PROGRAM === "iTerm.app" || !!process.env.ITERM_SESSION_ID,
19
+ image: (buffer, force = false) => {
20
+ if ((!logger.isIterm2 && !force) || !buffer) return;
21
+ // iTerm2 Inline Image Protocol: \x1b]1337;File=inline=1;size=...:[base64]\x07
22
+ const base64 = buffer.toString("base64");
23
+ process.stdout.write(`\x1b]1337;File=inline=1;size=${buffer.length}:${base64}\x07\n`);
24
+ }
25
+ };
26
+
27
+ export default logger;
@@ -0,0 +1,45 @@
1
+ import readline from "readline";
2
+ import chalk from "chalk";
3
+ import config from "./config-manager.js";
4
+ import { t } from "./i18n.js";
5
+ import { validateApiKey } from "./api.js";
6
+
7
+ export async function startOnboarding(banner = "") {
8
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
9
+ const question = (query) => new Promise((resolve) => rl.question(query, resolve));
10
+
11
+ console.clear();
12
+ if (banner) console.log(banner);
13
+
14
+ // 1. 设置语言
15
+ console.log(chalk.cyan("\n" + "=".repeat(50)));
16
+ const langIdx = await question(chalk.bold("\n请选择语言 / Select Language (1: English, 2: 中文) [1]: "));
17
+ const lang = langIdx === "2" ? "zh" : "en";
18
+ config.set("lang", lang);
19
+ console.log(chalk.green(`\n✓ Language set to: ${lang === "zh" ? "中文" : "English"}`));
20
+
21
+ // 2. 引导欢迎语
22
+ console.log(chalk.blue(`\n💡 ${t("ONBOARD_WELCOME")}`));
23
+ console.log(chalk.yellow(`🔗 ${t("ONBOARD_GET_LINK")}\n`));
24
+
25
+ // 3. 循环请求 API Key 直到校验成功
26
+ let valid = false;
27
+ while (!valid) {
28
+ const key = await question(chalk.bold(`🔑 ${t("ONBOARD_PROMPT")}`));
29
+ if (!key) continue;
30
+
31
+ console.log(chalk.blue(`\n⏳ ${t("ONBOARD_VALIDATING")}...`));
32
+ valid = await validateApiKey(key);
33
+
34
+ if (valid) {
35
+ config.set("apiKey", key);
36
+ console.log(chalk.green(`\n✨ ${t("ONBOARD_SUCCESS")}`));
37
+ } else {
38
+ console.log(chalk.red(`\n❌ ${t("ONBOARD_FAILED")}`));
39
+ console.log(chalk.yellow(`🔗 ${t("ONBOARD_GET_LINK")}\n`));
40
+ }
41
+ }
42
+
43
+ rl.close();
44
+ console.log(chalk.cyan("\n" + "=".repeat(50) + "\n"));
45
+ }