@yakumoryo/minimax-plan-usage 0.1.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.
@@ -0,0 +1,17 @@
1
+ {
2
+ "$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
3
+ "name": "@yakumoryo/minimax-plan-usage",
4
+ "version": "0.1.0",
5
+ "description": "Query quota and usage statistics for MiniMax Coding Plan service",
6
+ "owner": {
7
+ "name": "User"
8
+ },
9
+ "plugins": [
10
+ {
11
+ "name": "@yakumoryo/minimax-plan-usage",
12
+ "source": ".",
13
+ "category": "development",
14
+ "description": "Query quota and usage statistics for MiniMax Coding Plan service. Uses ANTHROPIC_AUTH_TOKEN and ANTHROPIC_BASE_URL from your Claude Code settings."
15
+ }
16
+ ]
17
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "minimax-plan-usage",
3
+ "description": "Query MiniMax Coding Plan usage statistics",
4
+ "version": "0.1.0",
5
+ "owner": "user"
6
+ }
package/README.md ADDED
@@ -0,0 +1,26 @@
1
+ # MiniMax Plan Usage
2
+
3
+ Query MiniMax Coding Plan usage statistics.
4
+
5
+ ## Usage
6
+
7
+ After installation, run:
8
+ ```
9
+ /minimax-plan-usage:usage-query
10
+ ```
11
+
12
+ ## How it works
13
+
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
+
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
+ - Otherwise → uses `https://api.minimaxi.com` (default)
19
+
20
+ ## Requirements
21
+
22
+ - Node.js installed
23
+ - `ANTHROPIC_AUTH_TOKEN` environment variable set
24
+ - `ANTHROPIC_BASE_URL` environment variable set
25
+
26
+ These are typically already configured in your Claude Code settings.
@@ -0,0 +1,32 @@
1
+ ---
2
+ name: usage-query-agent
3
+ description: Query MiniMax Coding Plan usage statistics for the current account. Triggered by the /minimax-plan-usage:usage-query command.
4
+ tools: Bash, Read, Skill, Glob, Grep
5
+ ---
6
+
7
+ # Usage Query Agent
8
+
9
+ You are responsible for querying the user's current usage information.
10
+
11
+ ## Critical constraint
12
+
13
+ **Run the query exactly once.** Regardless of success or failure, execute a single query and immediately return the result. No retries, no loops.
14
+
15
+ ## Execution
16
+
17
+ ### Invoke the skill
18
+
19
+ Call @minimax-plan-usage:usage-query-skill to perform the usage query.
20
+
21
+ The skill will run query-usage.mjs automatically, then return the result.
22
+
23
+ ### Report the outcome
24
+
25
+ Based on the skill output, respond to the user in Chinese.
26
+
27
+ ## Prohibited actions
28
+
29
+ - Do not run multiple queries
30
+ - Do not retry automatically after failure
31
+ - Do not ask the user whether to retry
32
+ - Do not modify files
@@ -0,0 +1,12 @@
1
+ ---
2
+ allowed-tools: all
3
+ description: Query MiniMax Coding Plan usage statistics
4
+ ---
5
+
6
+ # Usage Query
7
+
8
+ Invoke @minimax-plan-usage:usage-query-agent to retrieve the usage information for the current account.
9
+
10
+ ## Critical constraint
11
+
12
+ **Run the query exactly once** — regardless of success or failure, execute a single query and return the result immediately.
package/package.json ADDED
@@ -0,0 +1,15 @@
1
+ {
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"],
6
+ "files": [
7
+ "commands",
8
+ "agents",
9
+ "skills",
10
+ ".claude-plugin"
11
+ ],
12
+ "engines": {
13
+ "node": ">=18"
14
+ }
15
+ }
@@ -0,0 +1,29 @@
1
+ ---
2
+ name: usage-query-skill
3
+ description: Run the usage query script to retrieve account usage information for MiniMax Coding Plan. Only use when invoked by usage-query-agent.
4
+ allowed-tools: Bash, Read
5
+ ---
6
+
7
+ # MiniMax Usage Query Skill
8
+
9
+ Execute the usage query script and return the result.
10
+
11
+ ## Critical constraint
12
+
13
+ **Run the script exactly once** — regardless of success or failure, execute it once and return the outcome.
14
+
15
+ ## Execution
16
+
17
+ ### Run the query
18
+
19
+ Use Node.js to execute the bundled script:
20
+
21
+ ```bash
22
+ node skills/usage-query-skill/scripts/query-usage.mjs
23
+ ```
24
+
25
+ ### Return the result
26
+
27
+ After execution, return the result to the caller:
28
+ - **Success**: display the usage information in Chinese
29
+ - **Failure**: show the error details and likely cause
@@ -0,0 +1,148 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * MiniMax Usage Query Script
5
+ * Reads ANTHROPIC_BASE_URL to determine API endpoint
6
+ * Uses ANTHROPIC_AUTH_TOKEN as the API key
7
+ */
8
+
9
+ import https from 'https';
10
+
11
+ const baseUrl = process.env.ANTHROPIC_BASE_URL || '';
12
+ const authToken = process.env.ANTHROPIC_AUTH_TOKEN || '';
13
+
14
+ if (!authToken) {
15
+ console.error('Error: ANTHROPIC_AUTH_TOKEN is not set');
16
+ console.error('');
17
+ console.error('Set the environment variable and retry:');
18
+ console.error(' export ANTHROPIC_AUTH_TOKEN="your-token-here"');
19
+ process.exit(1);
20
+ }
21
+
22
+ let apiHost = 'https://api.minimaxi.com';
23
+
24
+ if (baseUrl.includes('minimax.io')) {
25
+ apiHost = 'https://minimax.io';
26
+ } else if (baseUrl.includes('minimaxi.cn')) {
27
+ apiHost = 'https://minimaxi.cn';
28
+ } else if (baseUrl.includes('minimaxi.com')) {
29
+ apiHost = 'https://api.minimaxi.com';
30
+ }
31
+
32
+ const apiUrl = `${apiHost}/v1/api/openplatform/coding_plan/remains`;
33
+
34
+ console.log(`MiniMax API Host: ${apiHost}`);
35
+ console.log('');
36
+
37
+ const queryUsage = () => {
38
+ return new Promise((resolve, reject) => {
39
+ const parsedUrl = new URL(apiUrl);
40
+ const options = {
41
+ hostname: parsedUrl.hostname,
42
+ port: 443,
43
+ path: parsedUrl.pathname,
44
+ method: 'GET',
45
+ headers: {
46
+ 'Authorization': `Bearer ${authToken}`,
47
+ 'Accept': 'application/json'
48
+ }
49
+ };
50
+
51
+ const req = https.request(options, (res) => {
52
+ let data = '';
53
+
54
+ res.on('data', (chunk) => {
55
+ data += chunk;
56
+ });
57
+
58
+ res.on('end', () => {
59
+ if (res.statusCode !== 200) {
60
+ if (res.statusCode === 401) {
61
+ return reject(new Error('认证失败,请检查 ANTHROPIC_AUTH_TOKEN 是否正确'));
62
+ }
63
+ return reject(new Error(`HTTP ${res.statusCode}: ${data}`));
64
+ }
65
+
66
+ try {
67
+ const json = JSON.parse(data);
68
+ if (!json.model_remains || json.model_remains.length === 0) {
69
+ console.log('无可用用量数据');
70
+ return resolve();
71
+ }
72
+
73
+ const m = json.model_remains[0];
74
+ const remaining = m.current_interval_usage_count;
75
+ const total = m.current_interval_total_count;
76
+ const used = total - remaining;
77
+ const percentage = Math.round((used / total) * 100);
78
+
79
+ const remainingMs = m.remains_time;
80
+ const hours = Math.floor(remainingMs / (1000 * 60 * 60));
81
+ const minutes = Math.floor((remainingMs % (1000 * 60 * 60)) / (1000 * 60));
82
+
83
+ const resetTime = new Date(m.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 weeklyRemaining = m.current_weekly_usage_count;
93
+ const weeklyTotal = m.current_weekly_total_count;
94
+ const weeklyUsed = weeklyTotal - weeklyRemaining;
95
+ const weeklyPercentage = Math.floor((weeklyUsed / weeklyTotal) * 100);
96
+ const weeklyRemainingMs = m.weekly_remains_time;
97
+ const weeklyDays = Math.floor(weeklyRemainingMs / (1000 * 60 * 60 * 24));
98
+ const weeklyHours = Math.floor((weeklyRemainingMs % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
99
+
100
+ const weeklyResetTime = new Date(m.weekly_end_time).toLocaleString('zh-CN', {
101
+ timeZone: 'Asia/Shanghai',
102
+ year: 'numeric',
103
+ month: '2-digit',
104
+ day: '2-digit',
105
+ hour: '2-digit',
106
+ minute: '2-digit',
107
+ });
108
+
109
+ const bar = '█'.repeat(Math.floor(percentage / 10)) + '░'.repeat(10 - Math.floor(percentage / 10));
110
+ const timeText = hours > 0 ? `${hours}小时${minutes}分钟` : `${minutes}分钟`;
111
+ const weeklyBar = '█'.repeat(Math.floor(weeklyPercentage / 10)) + '░'.repeat(10 - Math.floor(weeklyPercentage / 10));
112
+ const weeklyTimeText = weeklyDays > 0 ? `${weeklyDays}天${weeklyHours}小时` : `${weeklyHours}小时`;
113
+
114
+ console.log('MiniMax Coding Plan 用量状态');
115
+ console.log('----------------------------------------');
116
+ console.log(`模型: ${m.model_name}`);
117
+ console.log(`已用(5h): ${used.toLocaleString()} / ${total.toLocaleString()}`);
118
+ console.log(`进度: [${bar}] ${percentage}%`);
119
+ console.log(`剩余(5h): ${remaining.toLocaleString()} 次`);
120
+ console.log(`重置: ${resetTime} (约${timeText})`);
121
+ console.log('----------------------------------------');
122
+ console.log(`周用量: ${weeklyUsed.toLocaleString()} / ${weeklyTotal.toLocaleString()}`);
123
+ console.log(`周进度: [${weeklyBar}] ${weeklyPercentage}%`);
124
+ console.log(`周重置: ${weeklyResetTime} (约${weeklyTimeText})`);
125
+ console.log('----------------------------------------');
126
+
127
+ } catch (e) {
128
+ return reject(new Error(`解析响应失败: ${e.message}`));
129
+ }
130
+ resolve();
131
+ });
132
+ });
133
+
134
+ req.on('error', (error) => {
135
+ if (error.code === 'ECONNABORTED') {
136
+ return reject(new Error('请求超时,请检查网络连接'));
137
+ }
138
+ reject(error);
139
+ });
140
+
141
+ req.end();
142
+ });
143
+ };
144
+
145
+ queryUsage().catch((error) => {
146
+ console.error('查询失败:', error.message);
147
+ process.exit(1);
148
+ });