@redonvn/cli 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.
- package/README.md +99 -0
- package/bin/redai.js +22 -0
- package/dist/auth/client-id.d.ts +8 -0
- package/dist/auth/client-id.js +41 -0
- package/dist/auth/client-id.js.map +1 -0
- package/dist/auth/store.d.ts +16 -0
- package/dist/auth/store.js +39 -0
- package/dist/auth/store.js.map +1 -0
- package/dist/cli/commands/login.d.ts +6 -0
- package/dist/cli/commands/login.js +82 -0
- package/dist/cli/commands/login.js.map +1 -0
- package/dist/cli/commands/logout.d.ts +1 -0
- package/dist/cli/commands/logout.js +18 -0
- package/dist/cli/commands/logout.js.map +1 -0
- package/dist/cli/commands/oauth.d.ts +11 -0
- package/dist/cli/commands/oauth.js +311 -0
- package/dist/cli/commands/oauth.js.map +1 -0
- package/dist/cli/commands/serve.d.ts +7 -0
- package/dist/cli/commands/serve.js +24 -0
- package/dist/cli/commands/serve.js.map +1 -0
- package/dist/cli/commands/start.d.ts +1 -0
- package/dist/cli/commands/start.js +26 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/status.d.ts +1 -0
- package/dist/cli/commands/status.js +51 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +127 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli-router/detect.d.ts +13 -0
- package/dist/cli-router/detect.js +58 -0
- package/dist/cli-router/detect.js.map +1 -0
- package/dist/config.d.ts +12 -0
- package/dist/config.js +24 -0
- package/dist/config.js.map +1 -0
- package/dist/daemon/router.d.ts +17 -0
- package/dist/daemon/router.js +39 -0
- package/dist/daemon/router.js.map +1 -0
- package/dist/daemon/tunnel.d.ts +10 -0
- package/dist/daemon/tunnel.js +156 -0
- package/dist/daemon/tunnel.js.map +1 -0
- package/dist/llm/llm-request.d.ts +9 -0
- package/dist/llm/llm-request.js +98 -0
- package/dist/llm/llm-request.js.map +1 -0
- package/dist/llm/oauth/antigravity-oauth.d.ts +22 -0
- package/dist/llm/oauth/antigravity-oauth.js +128 -0
- package/dist/llm/oauth/antigravity-oauth.js.map +1 -0
- package/dist/llm/oauth/callback-server.d.ts +18 -0
- package/dist/llm/oauth/callback-server.js +78 -0
- package/dist/llm/oauth/callback-server.js.map +1 -0
- package/dist/llm/oauth/claude-oauth.d.ts +29 -0
- package/dist/llm/oauth/claude-oauth.js +115 -0
- package/dist/llm/oauth/claude-oauth.js.map +1 -0
- package/dist/llm/oauth/codex-oauth.d.ts +21 -0
- package/dist/llm/oauth/codex-oauth.js +137 -0
- package/dist/llm/oauth/codex-oauth.js.map +1 -0
- package/dist/llm/oauth/gemini-oauth.d.ts +26 -0
- package/dist/llm/oauth/gemini-oauth.js +132 -0
- package/dist/llm/oauth/gemini-oauth.js.map +1 -0
- package/dist/llm/oauth/iflow-oauth.d.ts +26 -0
- package/dist/llm/oauth/iflow-oauth.js +151 -0
- package/dist/llm/oauth/iflow-oauth.js.map +1 -0
- package/dist/llm/oauth/kimi-oauth.d.ts +16 -0
- package/dist/llm/oauth/kimi-oauth.js +126 -0
- package/dist/llm/oauth/kimi-oauth.js.map +1 -0
- package/dist/llm/oauth/open-browser.d.ts +5 -0
- package/dist/llm/oauth/open-browser.js +32 -0
- package/dist/llm/oauth/open-browser.js.map +1 -0
- package/dist/llm/oauth/pkce.d.ts +12 -0
- package/dist/llm/oauth/pkce.js +27 -0
- package/dist/llm/oauth/pkce.js.map +1 -0
- package/dist/llm/oauth/qwen-oauth.d.ts +27 -0
- package/dist/llm/oauth/qwen-oauth.js +138 -0
- package/dist/llm/oauth/qwen-oauth.js.map +1 -0
- package/dist/llm/oauth/store.d.ts +34 -0
- package/dist/llm/oauth/store.js +72 -0
- package/dist/llm/oauth/store.js.map +1 -0
- package/dist/llm/oauth/xai-oauth.d.ts +28 -0
- package/dist/llm/oauth/xai-oauth.js +132 -0
- package/dist/llm/oauth/xai-oauth.js.map +1 -0
- package/dist/llm/providers/antigravity.d.ts +23 -0
- package/dist/llm/providers/antigravity.js +103 -0
- package/dist/llm/providers/antigravity.js.map +1 -0
- package/dist/llm/providers/claude.d.ts +36 -0
- package/dist/llm/providers/claude.js +148 -0
- package/dist/llm/providers/claude.js.map +1 -0
- package/dist/llm/providers/codex.d.ts +23 -0
- package/dist/llm/providers/codex.js +122 -0
- package/dist/llm/providers/codex.js.map +1 -0
- package/dist/llm/providers/gemini.d.ts +23 -0
- package/dist/llm/providers/gemini.js +112 -0
- package/dist/llm/providers/gemini.js.map +1 -0
- package/dist/llm/providers/generic-client.d.ts +45 -0
- package/dist/llm/providers/generic-client.js +98 -0
- package/dist/llm/providers/generic-client.js.map +1 -0
- package/dist/llm/providers/iflow.d.ts +8 -0
- package/dist/llm/providers/iflow.js +15 -0
- package/dist/llm/providers/iflow.js.map +1 -0
- package/dist/llm/providers/kimi.d.ts +8 -0
- package/dist/llm/providers/kimi.js +16 -0
- package/dist/llm/providers/kimi.js.map +1 -0
- package/dist/llm/providers/qwen.d.ts +8 -0
- package/dist/llm/providers/qwen.js +15 -0
- package/dist/llm/providers/qwen.js.map +1 -0
- package/dist/llm/providers/xai.d.ts +8 -0
- package/dist/llm/providers/xai.js +15 -0
- package/dist/llm/providers/xai.js.map +1 -0
- package/dist/llm/selector.d.ts +14 -0
- package/dist/llm/selector.js +81 -0
- package/dist/llm/selector.js.map +1 -0
- package/dist/server/http-server.d.ts +22 -0
- package/dist/server/http-server.js +194 -0
- package/dist/server/http-server.js.map +1 -0
- package/dist/tools/bash.d.ts +7 -0
- package/dist/tools/bash.js +61 -0
- package/dist/tools/bash.js.map +1 -0
- package/dist/tools/edit.d.ts +4 -0
- package/dist/tools/edit.js +35 -0
- package/dist/tools/edit.js.map +1 -0
- package/dist/tools/glob.d.ts +5 -0
- package/dist/tools/glob.js +27 -0
- package/dist/tools/glob.js.map +1 -0
- package/dist/tools/grep.d.ts +5 -0
- package/dist/tools/grep.js +63 -0
- package/dist/tools/grep.js.map +1 -0
- package/dist/tools/read.d.ts +6 -0
- package/dist/tools/read.js +25 -0
- package/dist/tools/read.js.map +1 -0
- package/dist/tools/registry.d.ts +8 -0
- package/dist/tools/registry.js +43 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/run-cli.d.ts +7 -0
- package/dist/tools/run-cli.js +83 -0
- package/dist/tools/run-cli.js.map +1 -0
- package/dist/tools/webfetch.d.ts +7 -0
- package/dist/tools/webfetch.js +26 -0
- package/dist/tools/webfetch.js.map +1 -0
- package/dist/tools/write.d.ts +5 -0
- package/dist/tools/write.js +29 -0
- package/dist/tools/write.js.map +1 -0
- package/package.json +67 -0
package/README.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# @redonvn/cli
|
|
2
|
+
|
|
3
|
+
RedAI CLI — kết nối máy bạn với RedAI agent runtime. AI cloud agent có thể:
|
|
4
|
+
|
|
5
|
+
- **Thao tác máy** qua tools: Read / Write / Edit / Bash / Grep / Glob / WebFetch
|
|
6
|
+
- **Spawn code-CLI** có sẵn: `claude` / `codex` / `gemini`
|
|
7
|
+
- **Proxy LLM request** qua OAuth của bạn: Claude Code, ChatGPT, Gemini Code Assist, Antigravity, Qwen, Kimi, iFlow, xAI Grok
|
|
8
|
+
|
|
9
|
+
## Cài đặt
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm i -g @redonvn/cli
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Yêu cầu Node.js ≥ 18.17.
|
|
16
|
+
|
|
17
|
+
## Quick start
|
|
18
|
+
|
|
19
|
+
### 1. Đăng nhập RedAI
|
|
20
|
+
|
|
21
|
+
Tạo API key trên dashboard RedAI với permission `cli:connect`, sau đó:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
redai login
|
|
25
|
+
# Paste API key khi prompt
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### 2. (Tuỳ chọn) Đăng nhập OAuth provider để dùng quota của bạn
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
redai oauth claude # Claude Code (PKCE)
|
|
32
|
+
redai oauth codex # Sign in with ChatGPT
|
|
33
|
+
redai oauth gemini # Gemini Code Assist
|
|
34
|
+
redai oauth antigravity # Antigravity (Google)
|
|
35
|
+
redai oauth qwen # Qwen (device flow)
|
|
36
|
+
redai oauth kimi # Kimi (device flow)
|
|
37
|
+
redai oauth iflow # iFlow (OAuth hoặc cookie)
|
|
38
|
+
redai oauth xai # xAI Grok (OIDC)
|
|
39
|
+
|
|
40
|
+
redai oauth list # xem tất cả account đã login
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 3. Chọn mode
|
|
44
|
+
|
|
45
|
+
**Mode A — Tunnel WS với RedAI cloud** (AI agent trên RedAI dùng máy bạn làm runtime):
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
redai start
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Cloud worker gọi: `POST /cli/clients/<clientId>/actions/...`
|
|
52
|
+
|
|
53
|
+
**Mode B — HTTP local server** (Cursor / Cline / Claude Code trỏ tới localhost):
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
redai serve --port 8317 --api-key <key>
|
|
57
|
+
|
|
58
|
+
# Cursor config: baseURL = http://localhost:8317/v1, apiKey = <key>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Endpoints expose:
|
|
62
|
+
- `POST /v1/messages` → Claude
|
|
63
|
+
- `POST /v1/chat/completions` → Codex
|
|
64
|
+
- `POST /v1beta/models/*:action` → Gemini
|
|
65
|
+
- `POST /llm/<provider>/<rest>` → Generic passthrough cho mọi provider
|
|
66
|
+
|
|
67
|
+
## Lệnh đầy đủ
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
redai login [--api-key <k>] [--api-url <url>]
|
|
71
|
+
redai status
|
|
72
|
+
redai start
|
|
73
|
+
redai serve [--port 8317] [--host 127.0.0.1] [--api-key <k>]
|
|
74
|
+
redai logout
|
|
75
|
+
|
|
76
|
+
redai oauth <provider> [--account <name>] [--no-browser] [--cookie <c>]
|
|
77
|
+
redai oauth list
|
|
78
|
+
redai oauth logout <provider> [<account>]
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Files
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
~/.redai/
|
|
85
|
+
├── config.json # cliToken + clientId (chmod 600)
|
|
86
|
+
├── client.id # UUID stable của máy
|
|
87
|
+
└── oauth/
|
|
88
|
+
└── <provider>/<account>.json # OAuth token (chmod 600)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Bảo mật
|
|
92
|
+
|
|
93
|
+
- OAuth token **chỉ lưu local**, RedAI server không thấy.
|
|
94
|
+
- API key chỉ gửi qua HTTPS để verify một lần, sau đó dùng `cliToken` JWT 90 ngày.
|
|
95
|
+
- File chmod 600 — chỉ chủ máy đọc được.
|
|
96
|
+
|
|
97
|
+
## License
|
|
98
|
+
|
|
99
|
+
MIT
|
package/bin/redai.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// Tiny launcher. Real logic in `dist/cli/index.js` (or `src/cli/index.ts` via ts-node in dev).
|
|
5
|
+
try {
|
|
6
|
+
require('../dist/cli/index.js');
|
|
7
|
+
} catch (err) {
|
|
8
|
+
if (err && err.code === 'MODULE_NOT_FOUND') {
|
|
9
|
+
// Dev mode fallback
|
|
10
|
+
try {
|
|
11
|
+
require('ts-node/register/transpile-only');
|
|
12
|
+
require('../src/cli/index.ts');
|
|
13
|
+
} catch (devErr) {
|
|
14
|
+
console.error('[redai] Failed to load CLI: ' + (devErr && devErr.message ? devErr.message : devErr));
|
|
15
|
+
console.error('[redai] If you installed via `npm i -g @redai/cli`, please report this issue.');
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
} else {
|
|
19
|
+
console.error('[redai] Fatal:', err && err.message ? err.message : err);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Đọc UUID stable định danh máy. Tạo mới + lưu vào ~/.redai/client.id nếu chưa có.
|
|
3
|
+
* UUID này theo máy này suốt đời, kể cả khi user logout/login lại — để BE biết
|
|
4
|
+
* "vẫn là chiếc laptop X" và không tạo CliClient mới mỗi lần.
|
|
5
|
+
*/
|
|
6
|
+
export declare function loadOrCreateClientId(): string;
|
|
7
|
+
export declare function configDir(): string;
|
|
8
|
+
export declare function configFilePath(): string;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.loadOrCreateClientId = loadOrCreateClientId;
|
|
7
|
+
exports.configDir = configDir;
|
|
8
|
+
exports.configFilePath = configFilePath;
|
|
9
|
+
const crypto_1 = require("crypto");
|
|
10
|
+
const fs_1 = __importDefault(require("fs"));
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
12
|
+
const config_1 = require("../config");
|
|
13
|
+
/**
|
|
14
|
+
* Đọc UUID stable định danh máy. Tạo mới + lưu vào ~/.redai/client.id nếu chưa có.
|
|
15
|
+
* UUID này theo máy này suốt đời, kể cả khi user logout/login lại — để BE biết
|
|
16
|
+
* "vẫn là chiếc laptop X" và không tạo CliClient mới mỗi lần.
|
|
17
|
+
*/
|
|
18
|
+
function loadOrCreateClientId() {
|
|
19
|
+
ensureDir();
|
|
20
|
+
if (fs_1.default.existsSync(config_1.REDAI_CLIENT_ID_FILE)) {
|
|
21
|
+
const existing = fs_1.default.readFileSync(config_1.REDAI_CLIENT_ID_FILE, 'utf8').trim();
|
|
22
|
+
if (existing)
|
|
23
|
+
return existing;
|
|
24
|
+
}
|
|
25
|
+
const generated = `dsk-${(0, crypto_1.randomUUID)()}`;
|
|
26
|
+
fs_1.default.writeFileSync(config_1.REDAI_CLIENT_ID_FILE, generated, { encoding: 'utf8', mode: 0o600 });
|
|
27
|
+
return generated;
|
|
28
|
+
}
|
|
29
|
+
function ensureDir() {
|
|
30
|
+
if (!fs_1.default.existsSync(config_1.REDAI_CONFIG_DIR)) {
|
|
31
|
+
fs_1.default.mkdirSync(config_1.REDAI_CONFIG_DIR, { recursive: true, mode: 0o700 });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function configDir() {
|
|
35
|
+
ensureDir();
|
|
36
|
+
return config_1.REDAI_CONFIG_DIR;
|
|
37
|
+
}
|
|
38
|
+
function configFilePath() {
|
|
39
|
+
return path_1.default.join(config_1.REDAI_CONFIG_DIR, 'config.json');
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=client-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-id.js","sourceRoot":"","sources":["../../src/auth/client-id.ts"],"names":[],"mappings":";;;;;AAUA,oDASC;AAQD,8BAGC;AAED,wCAEC;AAlCD,mCAAoC;AACpC,4CAAoB;AACpB,gDAAwB;AACxB,sCAAmE;AAEnE;;;;GAIG;AACH,SAAgB,oBAAoB;IAClC,SAAS,EAAE,CAAC;IACZ,IAAI,YAAE,CAAC,UAAU,CAAC,6BAAoB,CAAC,EAAE,CAAC;QACxC,MAAM,QAAQ,GAAG,YAAE,CAAC,YAAY,CAAC,6BAAoB,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QACtE,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAC;IAChC,CAAC;IACD,MAAM,SAAS,GAAG,OAAO,IAAA,mBAAU,GAAE,EAAE,CAAC;IACxC,YAAE,CAAC,aAAa,CAAC,6BAAoB,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACrF,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,SAAS;IAChB,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,yBAAgB,CAAC,EAAE,CAAC;QACrC,YAAE,CAAC,SAAS,CAAC,yBAAgB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACnE,CAAC;AACH,CAAC;AAED,SAAgB,SAAS;IACvB,SAAS,EAAE,CAAC;IACZ,OAAO,yBAAgB,CAAC;AAC1B,CAAC;AAED,SAAgB,cAAc;IAC5B,OAAO,cAAI,CAAC,IAAI,CAAC,yBAAgB,EAAE,aAAa,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface RedaiCliConfig {
|
|
2
|
+
cliToken: string;
|
|
3
|
+
clientId: string;
|
|
4
|
+
wsUrl: string;
|
|
5
|
+
apiBaseUrl: string;
|
|
6
|
+
userId: number;
|
|
7
|
+
userEmail: string | null;
|
|
8
|
+
userName: string | null;
|
|
9
|
+
expiresAt: number;
|
|
10
|
+
projectSchemaId: string;
|
|
11
|
+
/** Tools BE đã bootstrap cho máy này (chỉ informational, không enforce ở CLI). */
|
|
12
|
+
registeredTools: string[];
|
|
13
|
+
}
|
|
14
|
+
export declare function loadConfig(): RedaiCliConfig | null;
|
|
15
|
+
export declare function saveConfig(cfg: RedaiCliConfig): void;
|
|
16
|
+
export declare function clearConfig(): void;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.loadConfig = loadConfig;
|
|
7
|
+
exports.saveConfig = saveConfig;
|
|
8
|
+
exports.clearConfig = clearConfig;
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const config_1 = require("../config");
|
|
11
|
+
function ensureDir() {
|
|
12
|
+
if (!fs_1.default.existsSync(config_1.REDAI_CONFIG_DIR)) {
|
|
13
|
+
fs_1.default.mkdirSync(config_1.REDAI_CONFIG_DIR, { recursive: true, mode: 0o700 });
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function loadConfig() {
|
|
17
|
+
if (!fs_1.default.existsSync(config_1.REDAI_CONFIG_FILE))
|
|
18
|
+
return null;
|
|
19
|
+
try {
|
|
20
|
+
const raw = fs_1.default.readFileSync(config_1.REDAI_CONFIG_FILE, 'utf8');
|
|
21
|
+
return JSON.parse(raw);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function saveConfig(cfg) {
|
|
28
|
+
ensureDir();
|
|
29
|
+
fs_1.default.writeFileSync(config_1.REDAI_CONFIG_FILE, JSON.stringify(cfg, null, 2), {
|
|
30
|
+
encoding: 'utf8',
|
|
31
|
+
mode: 0o600,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
function clearConfig() {
|
|
35
|
+
if (fs_1.default.existsSync(config_1.REDAI_CONFIG_FILE)) {
|
|
36
|
+
fs_1.default.unlinkSync(config_1.REDAI_CONFIG_FILE);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/auth/store.ts"],"names":[],"mappings":";;;;;AAuBA,gCAQC;AAED,gCAMC;AAED,kCAIC;AA7CD,4CAAoB;AACpB,sCAAgE;AAgBhE,SAAS,SAAS;IAChB,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,yBAAgB,CAAC,EAAE,CAAC;QACrC,YAAE,CAAC,SAAS,CAAC,yBAAgB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACnE,CAAC;AACH,CAAC;AAED,SAAgB,UAAU;IACxB,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,0BAAiB,CAAC;QAAE,OAAO,IAAI,CAAC;IACnD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAE,CAAC,YAAY,CAAC,0BAAiB,EAAE,MAAM,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAmB,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAgB,UAAU,CAAC,GAAmB;IAC5C,SAAS,EAAE,CAAC;IACZ,YAAE,CAAC,aAAa,CAAC,0BAAiB,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;QAChE,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,KAAK;KACZ,CAAC,CAAC;AACL,CAAC;AAED,SAAgB,WAAW;IACzB,IAAI,YAAE,CAAC,UAAU,CAAC,0BAAiB,CAAC,EAAE,CAAC;QACrC,YAAE,CAAC,UAAU,CAAC,0BAAiB,CAAC,CAAC;IACnC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.loginCommand = loginCommand;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const os_1 = __importDefault(require("os"));
|
|
10
|
+
const prompts_1 = __importDefault(require("prompts"));
|
|
11
|
+
const config_1 = require("../../config");
|
|
12
|
+
const client_id_1 = require("../../auth/client-id");
|
|
13
|
+
const store_1 = require("../../auth/store");
|
|
14
|
+
const detect_1 = require("../../cli-router/detect");
|
|
15
|
+
async function loginCommand(options = {}) {
|
|
16
|
+
const apiBaseUrl = (options.apiUrl ?? config_1.DEFAULT_API_BASE_URL).replace(/\/+$/, '');
|
|
17
|
+
let apiKey = options.apiKey;
|
|
18
|
+
if (!apiKey) {
|
|
19
|
+
const response = await (0, prompts_1.default)({
|
|
20
|
+
type: 'password',
|
|
21
|
+
name: 'apiKey',
|
|
22
|
+
message: 'Paste your RedAI API key (with permission "cli:connect"):',
|
|
23
|
+
validate: (v) => typeof v === 'string' && v.trim().length >= 8 ? true : 'API key looks too short',
|
|
24
|
+
});
|
|
25
|
+
apiKey = response.apiKey?.trim();
|
|
26
|
+
}
|
|
27
|
+
if (!apiKey) {
|
|
28
|
+
console.error(chalk_1.default.red('No API key provided. Aborting.'));
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
const clientId = (0, client_id_1.loadOrCreateClientId)();
|
|
32
|
+
const { capabilities, cliDetected } = (0, detect_1.detectCapabilities)();
|
|
33
|
+
console.log(chalk_1.default.cyan('→ Verifying API key with'), apiBaseUrl);
|
|
34
|
+
let result;
|
|
35
|
+
try {
|
|
36
|
+
const res = await axios_1.default.post(`${apiBaseUrl}/cli/auth/verify`, {
|
|
37
|
+
apiKey,
|
|
38
|
+
clientId,
|
|
39
|
+
hostname: os_1.default.hostname(),
|
|
40
|
+
platform: process.platform,
|
|
41
|
+
cliVersion: config_1.CLI_VERSION,
|
|
42
|
+
capabilities,
|
|
43
|
+
cliDetected,
|
|
44
|
+
}, {
|
|
45
|
+
timeout: 15000,
|
|
46
|
+
headers: { 'user-agent': `redai-cli/${config_1.CLI_VERSION}` },
|
|
47
|
+
});
|
|
48
|
+
result = res.data;
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
if (axios_1.default.isAxiosError(err) && err.response) {
|
|
52
|
+
console.error(chalk_1.default.red('✗ Login failed:'), err.response.data);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
console.error(chalk_1.default.red('✗ Login failed:'), err instanceof Error ? err.message : err);
|
|
56
|
+
}
|
|
57
|
+
process.exit(1);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
(0, store_1.saveConfig)({
|
|
61
|
+
cliToken: result.cliToken,
|
|
62
|
+
clientId: result.clientId,
|
|
63
|
+
wsUrl: result.wsUrl,
|
|
64
|
+
apiBaseUrl,
|
|
65
|
+
userId: result.user.id,
|
|
66
|
+
userEmail: result.user.email,
|
|
67
|
+
userName: result.user.name,
|
|
68
|
+
expiresAt: result.expiresAt,
|
|
69
|
+
projectSchemaId: result.projectSchemaId,
|
|
70
|
+
registeredTools: result.registeredTools,
|
|
71
|
+
});
|
|
72
|
+
console.log();
|
|
73
|
+
console.log(chalk_1.default.green('✓ Logged in.'));
|
|
74
|
+
console.log(` ${chalk_1.default.gray('User :')} ${result.user.name ?? result.user.email ?? result.user.id}`);
|
|
75
|
+
console.log(` ${chalk_1.default.gray('Client ID :')} ${result.clientId}`);
|
|
76
|
+
console.log(` ${chalk_1.default.gray('Schema :')} ${result.projectSchemaId}`);
|
|
77
|
+
console.log(` ${chalk_1.default.gray('Tools :')} ${result.registeredTools.join(', ') || '(none)'}`);
|
|
78
|
+
console.log(` ${chalk_1.default.gray('Expires :')} ${new Date(result.expiresAt).toISOString()}`);
|
|
79
|
+
console.log();
|
|
80
|
+
console.log(chalk_1.default.dim('Next: run `redai start` to keep this machine connected.'));
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/cli/commands/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function logoutCommand(): Promise<void>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.logoutCommand = logoutCommand;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const store_1 = require("../../auth/store");
|
|
9
|
+
async function logoutCommand() {
|
|
10
|
+
const cfg = (0, store_1.loadConfig)();
|
|
11
|
+
if (!cfg) {
|
|
12
|
+
console.log(chalk_1.default.yellow('Not logged in.'));
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
(0, store_1.clearConfig)();
|
|
16
|
+
console.log(chalk_1.default.green('✓ Logged out. Token removed from ~/.redai/config.json.'));
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=logout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../../src/cli/commands/logout.ts"],"names":[],"mappings":";;;;;AAGA,sCAQC;AAXD,kDAA0B;AAC1B,4CAA2D;AAEpD,KAAK,UAAU,aAAa;IACjC,MAAM,GAAG,GAAG,IAAA,kBAAU,GAAE,CAAC;IACzB,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC;QAC5C,OAAO;IACT,CAAC;IACD,IAAA,mBAAW,GAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC,CAAC;AACrF,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface OAuthCommandOptions {
|
|
2
|
+
provider: string;
|
|
3
|
+
account?: string;
|
|
4
|
+
noBrowser?: boolean;
|
|
5
|
+
/** Cho iFlow: paste cookie thay vì OAuth flow. */
|
|
6
|
+
cookie?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function oauthCommand(options: OAuthCommandOptions): Promise<void>;
|
|
9
|
+
export declare function oauthListCommand(): Promise<void>;
|
|
10
|
+
export declare function oauthLogoutCommand(provider: string, account?: string): Promise<void>;
|
|
11
|
+
export {};
|