@yakumoryo/minimax-plan-usage 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -14,7 +14,6 @@ After installation, run:
14
14
  The plugin uses the same `ANTHROPIC_AUTH_TOKEN` and `ANTHROPIC_BASE_URL` that Claude Code uses. Based on the base URL, it determines the correct MiniMax API endpoint:
15
15
 
16
16
  - If `ANTHROPIC_BASE_URL` contains `minimax.io` → uses `https://minimax.io`
17
- - If `ANTHROPIC_BASE_URL` contains `minimaxi.cn` → uses `https://minimaxi.cn`
18
17
  - Otherwise → uses `https://api.minimaxi.com` (default)
19
18
 
20
19
  ## Requirements
package/package.json CHANGED
@@ -1,15 +1,25 @@
1
1
  {
2
2
  "name": "@yakumoryo/minimax-plan-usage",
3
- "version": "0.1.0",
4
- "description": "Claude Code plugin for MiniMax Coding Plan usage statistics",
5
- "keywords": ["claude", "claude-code", "plugin", "minimax"],
3
+ "version": "0.2.0",
4
+ "description": "MiniMax Coding Plan setup helper and usage query tool",
5
+ "type": "module",
6
+ "keywords": ["minimax", "claude-code"],
6
7
  "files": [
7
8
  "commands",
8
9
  "agents",
9
10
  "skills",
10
- ".claude-plugin"
11
+ ".claude-plugin",
12
+ "setup.js",
13
+ "query.js"
11
14
  ],
12
15
  "engines": {
13
16
  "node": ">=18"
17
+ },
18
+ "bin": {
19
+ "minimax-plan-usage": "./query.js"
20
+ },
21
+ "scripts": {
22
+ "setup": "node setup.js",
23
+ "query": "node query.js"
14
24
  }
15
- }
25
+ }
package/query.js ADDED
@@ -0,0 +1,150 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * MiniMax Coding Plan Usage Query
5
+ * Uses ANTHROPIC_AUTH_TOKEN and ANTHROPIC_BASE_URL from environment
6
+ */
7
+
8
+ import https from 'https';
9
+ import { spawn } from 'child_process';
10
+
11
+ const API_HOST = 'https://api.minimaxi.com';
12
+
13
+ const queryUsage = () => {
14
+ return new Promise((resolve, reject) => {
15
+ const apiUrl = `${API_HOST}/v1/api/openplatform/coding_plan/remains`;
16
+ const authToken = process.env.ANTHROPIC_AUTH_TOKEN;
17
+
18
+ if (!authToken) {
19
+ return reject(new Error('ANTHROPIC_AUTH_TOKEN not set. Run: npx @yakumoryo/minimax-plan-usage setup <token>'));
20
+ }
21
+
22
+ const parsedUrl = new URL(apiUrl);
23
+ const options = {
24
+ hostname: parsedUrl.hostname,
25
+ port: 443,
26
+ path: parsedUrl.pathname,
27
+ method: 'GET',
28
+ headers: {
29
+ 'Authorization': `Bearer ${authToken}`,
30
+ 'Accept': 'application/json'
31
+ }
32
+ };
33
+
34
+ const req = https.request(options, (res) => {
35
+ let data = '';
36
+
37
+ res.on('data', (chunk) => {
38
+ data += chunk;
39
+ });
40
+
41
+ res.on('end', () => {
42
+ if (res.statusCode !== 200) {
43
+ if (res.statusCode === 401) {
44
+ return reject(new Error('认证失败,请检查 ANTHROPIC_AUTH_TOKEN 是否正确'));
45
+ }
46
+ return reject(new Error(`HTTP ${res.statusCode}: ${data}`));
47
+ }
48
+
49
+ try {
50
+ const json = JSON.parse(data);
51
+ if (!json.model_remains || json.model_remains.length === 0) {
52
+ console.log('无可用用量数据');
53
+ return resolve();
54
+ }
55
+
56
+ const m = json.model_remains[0];
57
+ const remaining = m.current_interval_usage_count;
58
+ const total = m.current_interval_total_count;
59
+ const used = total - remaining;
60
+ const percentage = Math.round((used / total) * 100);
61
+
62
+ const remainingMs = m.remains_time;
63
+ const hours = Math.floor(remainingMs / (1000 * 60 * 60));
64
+ const minutes = Math.floor((remainingMs % (1000 * 60 * 60)) / (1000 * 60));
65
+
66
+ const resetTime = new Date(m.end_time).toLocaleString('zh-CN', {
67
+ timeZone: 'Asia/Shanghai',
68
+ year: 'numeric',
69
+ month: '2-digit',
70
+ day: '2-digit',
71
+ hour: '2-digit',
72
+ minute: '2-digit',
73
+ });
74
+
75
+ const weeklyRemaining = m.current_weekly_usage_count;
76
+ const weeklyTotal = m.current_weekly_total_count;
77
+ const weeklyUsed = weeklyTotal - weeklyRemaining;
78
+ const weeklyPercentage = Math.floor((weeklyUsed / weeklyTotal) * 100);
79
+ const weeklyRemainingMs = m.weekly_remains_time;
80
+ const weeklyDays = Math.floor(weeklyRemainingMs / (1000 * 60 * 60 * 24));
81
+ const weeklyHours = Math.floor((weeklyRemainingMs % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
82
+
83
+ const weeklyResetTime = new Date(m.weekly_end_time).toLocaleString('zh-CN', {
84
+ timeZone: 'Asia/Shanghai',
85
+ year: 'numeric',
86
+ month: '2-digit',
87
+ day: '2-digit',
88
+ hour: '2-digit',
89
+ minute: '2-digit',
90
+ });
91
+
92
+ const bar = '█'.repeat(Math.floor(percentage / 10)) + '░'.repeat(10 - Math.floor(percentage / 10));
93
+ const timeText = hours > 0 ? `${hours}小时${minutes}分钟` : `${minutes}分钟`;
94
+ const weeklyBar = '█'.repeat(Math.floor(weeklyPercentage / 10)) + '░'.repeat(10 - Math.floor(weeklyPercentage / 10));
95
+ const weeklyTimeText = weeklyDays > 0 ? `${weeklyDays}天${weeklyHours}小时` : `${weeklyHours}小时`;
96
+
97
+ console.log('');
98
+ console.log('MiniMax Coding Plan 用量状态');
99
+ console.log('----------------------------------------');
100
+ console.log(`模型: ${m.model_name}`);
101
+ console.log(`已用(5h): ${used.toLocaleString()} / ${total.toLocaleString()}`);
102
+ console.log(`进度: [${bar}] ${percentage}%`);
103
+ console.log(`剩余(5h): ${remaining.toLocaleString()} 次`);
104
+ console.log(`重置: ${resetTime} (约${timeText})`);
105
+ console.log('----------------------------------------');
106
+ console.log(`周用量: ${weeklyUsed.toLocaleString()} / ${weeklyTotal.toLocaleString()}`);
107
+ console.log(`周进度: [${weeklyBar}] ${weeklyPercentage}%`);
108
+ console.log(`周重置: ${weeklyResetTime} (约${weeklyTimeText})`);
109
+ console.log('----------------------------------------');
110
+ console.log('');
111
+
112
+ } catch (e) {
113
+ return reject(new Error(`解析响应失败: ${e.message}`));
114
+ }
115
+ resolve();
116
+ });
117
+ });
118
+
119
+ req.on('error', (error) => {
120
+ if (error.code === 'ECONNABORTED') {
121
+ return reject(new Error('请求超时,请检查网络连接'));
122
+ }
123
+ reject(error);
124
+ });
125
+
126
+ req.end();
127
+ });
128
+ };
129
+
130
+ const command = process.argv[2];
131
+
132
+ if (command === 'query') {
133
+ console.log('MiniMax API Host:', API_HOST);
134
+ queryUsage()
135
+ .then(() => process.exit(0))
136
+ .catch((error) => {
137
+ console.error('查询失败:', error.message);
138
+ process.exit(1);
139
+ });
140
+ } else {
141
+ console.log('MiniMax Coding Plan Helper');
142
+ console.log('');
143
+ console.log('Usage:');
144
+ console.log(' npx @yakumoryo/minimax-plan-usage setup <your-token> # 配置API Key');
145
+ console.log(' npx @yakumoryo/minimax-plan-usage query # 查询用量');
146
+ console.log('');
147
+ console.log('Examples:');
148
+ console.log(' npx @yakumoryo/minimax-plan-usage setup sk-cp-jErbHQzWz1agLaJeOrtPxZJp93PjkVpc');
149
+ console.log(' npx @yakumoryo/minimax-plan-usage query');
150
+ }
package/setup.js ADDED
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * MiniMax Coding Plan Setup Helper
5
+ * Configures Claude Code to use MiniMax API
6
+ */
7
+
8
+ import { readFileSync, writeFileSync } from 'fs';
9
+ import { homedir } from 'os';
10
+ import { join } from 'path';
11
+
12
+ const SETTINGS_PATH = join(homedir(), '.claude', 'settings.json');
13
+
14
+ const API_URL = 'https://api.minimaxi.com';
15
+
16
+ function getSettings() {
17
+ try {
18
+ return JSON.parse(readFileSync(SETTINGS_PATH, 'utf-8'));
19
+ } catch {
20
+ return { env: {}, permissions: { allow: [], deny: [] }, enabledPlugins: {} };
21
+ }
22
+ }
23
+
24
+ function saveSettings(settings) {
25
+ writeFileSync(SETTINGS_PATH, JSON.stringify(settings, null, 2));
26
+ }
27
+
28
+ function setup(token) {
29
+ if (!token || !token.startsWith('sk-cp-')) {
30
+ console.error('Error: Invalid token format. Token should start with "sk-cp-"');
31
+ console.error('');
32
+ console.error('Usage: npx @yakumoryo/minimax-plan-usage setup <your-token>');
33
+ console.error('');
34
+ console.error('Example:');
35
+ console.error(' npx @yakumoryo/minimax-plan-usage setup sk-cp-jErbHQzWz1agLaJeOrtPxZJp93PjkVpc-x0930-FUjFnVWxCW98YlYM8');
36
+ process.exit(1);
37
+ }
38
+
39
+ const settings = getSettings();
40
+
41
+ // Ensure env object exists
42
+ if (!settings.env) {
43
+ settings.env = {};
44
+ }
45
+
46
+ // Set MiniMax environment variables
47
+ settings.env.ANTHROPIC_AUTH_TOKEN = token;
48
+ settings.env.ANTHROPIC_BASE_URL = `${API_URL}/anthropic`;
49
+
50
+ // Add default model settings if not present
51
+ if (!settings.env.ANTHROPIC_MODEL) {
52
+ settings.env.ANTHROPIC_MODEL = 'MiniMax-M2.7';
53
+ }
54
+ if (!settings.env.ANTHROPIC_DEFAULT_HAIKU_MODEL) {
55
+ settings.env.ANTHROPIC_DEFAULT_HAIKU_MODEL = 'MiniMax-M2.7';
56
+ }
57
+ if (!settings.env.ANTHROPIC_DEFAULT_SONNET_MODEL) {
58
+ settings.env.ANTHROPIC_DEFAULT_SONNET_MODEL = 'MiniMax-M2.7';
59
+ }
60
+ if (!settings.env.ANTHROPIC_DEFAULT_OPUS_MODEL) {
61
+ settings.env.ANTHROPIC_DEFAULT_OPUS_MODEL = 'MiniMax-M2.7';
62
+ }
63
+
64
+ // Ensure permissions exist
65
+ if (!settings.permissions) {
66
+ settings.permissions = { allow: ['Bash(*)', 'Read(*)', 'Write(*)', 'Edit(*)'], deny: [] };
67
+ }
68
+
69
+ // Add plugin if not present
70
+ if (!settings.enabledPlugins) {
71
+ settings.enabledPlugins = {};
72
+ }
73
+
74
+ saveSettings(settings);
75
+
76
+ console.log('');
77
+ console.log('✅ MiniMax Coding Plan configured successfully!');
78
+ console.log('');
79
+ console.log('Settings updated:');
80
+ console.log(` ANTHROPIC_AUTH_TOKEN: ${token.slice(0, 20)}...`);
81
+ console.log(` ANTHROPIC_BASE_URL: ${API_URL}/anthropic`);
82
+ console.log('');
83
+ console.log('Restart Claude Code to apply changes, then run:');
84
+ console.log(' /minimax-plan-usage:usage-query');
85
+ }
86
+
87
+ const command = process.argv[2];
88
+ if (command === 'setup') {
89
+ const token = process.argv[3];
90
+ setup(token);
91
+ } else {
92
+ console.log('MiniMax Coding Plan Helper');
93
+ console.log('');
94
+ console.log('Usage:');
95
+ console.log(' npx @yakumoryo/minimax-plan-usage setup <your-token>');
96
+ console.log('');
97
+ console.log('Example:');
98
+ console.log(' npx @yakumoryo/minimax-plan-usage setup sk-cp-jErbHQzWz1agLaJeOrtPxZJp93PjkVpc');
99
+ console.log('');
100
+ console.log('To query usage after setup:');
101
+ console.log(' npx @yakumoryo/minimax-plan-usage query');
102
+ }
@@ -23,9 +23,7 @@ let apiHost = 'https://api.minimaxi.com';
23
23
 
24
24
  if (baseUrl.includes('minimax.io')) {
25
25
  apiHost = 'https://minimax.io';
26
- } else if (baseUrl.includes('minimaxi.cn')) {
27
- apiHost = 'https://minimaxi.cn';
28
- } else if (baseUrl.includes('minimaxi.com')) {
26
+ } else {
29
27
  apiHost = 'https://api.minimaxi.com';
30
28
  }
31
29