icbauggw 1.0.0 → 1.0.2
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/SETUP.md +47 -0
- package/package.json +1 -1
- package/src/commands/status.js +3 -2
- package/src/utils/api.js +14 -13
package/SETUP.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Hướng dẫn cài đặt CLI - Augment Session Rotator
|
|
2
|
+
|
|
3
|
+
## Yêu cầu
|
|
4
|
+
|
|
5
|
+
- Node.js >= 18
|
|
6
|
+
|
|
7
|
+
## Cài đặt
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g icbauggw
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Đăng nhập
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
icbauggw login
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Nhập username và password được cấp. Token sẽ lưu tại `~/.icb-aug/token`.
|
|
20
|
+
|
|
21
|
+
## Sử dụng
|
|
22
|
+
|
|
23
|
+
### Chuyển session
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
icbauggw switch
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Lệnh này lấy account tiếp theo từ pool và ghi vào `~/.augment/session.json`. Chạy lại mỗi khi cần đổi account.
|
|
30
|
+
|
|
31
|
+
### Xem trạng thái
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
icbauggw status
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Hiển thị account đang dùng, credit usage và số lượng account trong pool.
|
|
38
|
+
|
|
39
|
+
## Lưu ý
|
|
40
|
+
|
|
41
|
+
- Sau khi `switch`, restart lại Augment extension để nó đọc session mới.
|
|
42
|
+
- Nếu gặp lỗi `Session expired`, chạy lại `icbauggw login`.
|
|
43
|
+
- Nếu cần trỏ sang server khác (dev/test), set env:
|
|
44
|
+
```bash
|
|
45
|
+
ICBAUGGW_API_URL=http://localhost:3000 icbauggw login
|
|
46
|
+
```
|
|
47
|
+
|
package/package.json
CHANGED
package/src/commands/status.js
CHANGED
|
@@ -22,8 +22,9 @@ async function statusCommand() {
|
|
|
22
22
|
const pct = Math.round((used / total) * 100);
|
|
23
23
|
console.log(` Credit: ${used.toLocaleString()} / ${total.toLocaleString()} (${pct}%)`);
|
|
24
24
|
}
|
|
25
|
-
if (data.current.
|
|
26
|
-
|
|
25
|
+
if (data.current.currentClient) {
|
|
26
|
+
const c = data.current.currentClient;
|
|
27
|
+
console.log(` Client: ${c.hostname || '—'} (${c.ip || '—'})`);
|
|
27
28
|
}
|
|
28
29
|
console.log();
|
|
29
30
|
}
|
package/src/utils/api.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
const os = require(
|
|
2
|
-
const { loadToken } = require(
|
|
1
|
+
const os = require("os");
|
|
2
|
+
const { loadToken } = require("./token");
|
|
3
3
|
|
|
4
|
-
const DEFAULT_API_URL = '
|
|
4
|
+
// const DEFAULT_API_URL = 'https://icbauggw.quangit.site';
|
|
5
|
+
const DEFAULT_API_URL = "http://localhost:3000";
|
|
5
6
|
|
|
6
7
|
function getBaseURL() {
|
|
7
8
|
return process.env.ICBAUGGW_API_URL || DEFAULT_API_URL;
|
|
@@ -10,13 +11,14 @@ function getBaseURL() {
|
|
|
10
11
|
function getLocalIP() {
|
|
11
12
|
const interfaces = os.networkInterfaces();
|
|
12
13
|
// Skip virtual/VPN adapters — prefer real Ethernet/Wi-Fi
|
|
13
|
-
const skipPatterns =
|
|
14
|
+
const skipPatterns =
|
|
15
|
+
/tailscale|vpn|virtual|vethernet|bluetooth|loopback|docker|vbox|vmware|wsl/i;
|
|
14
16
|
|
|
15
17
|
// First pass: find IP from real adapters (Ethernet, Wi-Fi)
|
|
16
18
|
for (const [name, addrs] of Object.entries(interfaces)) {
|
|
17
19
|
if (skipPatterns.test(name)) continue;
|
|
18
20
|
for (const iface of addrs) {
|
|
19
|
-
if (iface.family ===
|
|
21
|
+
if (iface.family === "IPv4" && !iface.internal) {
|
|
20
22
|
return iface.address;
|
|
21
23
|
}
|
|
22
24
|
}
|
|
@@ -24,12 +26,12 @@ function getLocalIP() {
|
|
|
24
26
|
// Fallback: any non-internal IPv4
|
|
25
27
|
for (const addrs of Object.values(interfaces)) {
|
|
26
28
|
for (const iface of addrs) {
|
|
27
|
-
if (iface.family ===
|
|
29
|
+
if (iface.family === "IPv4" && !iface.internal) {
|
|
28
30
|
return iface.address;
|
|
29
31
|
}
|
|
30
32
|
}
|
|
31
33
|
}
|
|
32
|
-
return
|
|
34
|
+
return "127.0.0.1";
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
async function apiRequest(method, path, body = null) {
|
|
@@ -37,12 +39,12 @@ async function apiRequest(method, path, body = null) {
|
|
|
37
39
|
const token = loadToken();
|
|
38
40
|
|
|
39
41
|
const headers = {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
"Content-Type": "application/json",
|
|
43
|
+
"X-Client-IP": getLocalIP(),
|
|
44
|
+
"X-Client-Hostname": os.hostname(),
|
|
43
45
|
};
|
|
44
46
|
if (token) {
|
|
45
|
-
headers[
|
|
47
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
const options = { method, headers };
|
|
@@ -62,7 +64,7 @@ async function apiRequest(method, path, body = null) {
|
|
|
62
64
|
|
|
63
65
|
return data;
|
|
64
66
|
} catch (err) {
|
|
65
|
-
if (err.cause && err.cause.code ===
|
|
67
|
+
if (err.cause && err.cause.code === "ECONNREFUSED") {
|
|
66
68
|
throw new Error(`Could not connect to server at ${getBaseURL()}`);
|
|
67
69
|
}
|
|
68
70
|
throw err;
|
|
@@ -70,4 +72,3 @@ async function apiRequest(method, path, body = null) {
|
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
module.exports = { apiRequest, getBaseURL };
|
|
73
|
-
|