indusagi-coding-agent 0.1.14 → 0.1.21
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/CHANGELOG.md +80 -0
- package/dist/cli/args.d.ts +1 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +19 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/login-handler.d.ts +20 -0
- package/dist/cli/login-handler.d.ts.map +1 -0
- package/dist/cli/login-handler.js +413 -0
- package/dist/cli/login-handler.js.map +1 -0
- package/dist/core/auth-storage.d.ts +56 -19
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +207 -53
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/model-registry.d.ts +17 -2
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +20 -4
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.js +2 -2
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +10 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/task-session-manager.d.ts.map +1 -1
- package/dist/core/task-session-manager.js +7 -1
- package/dist/core/task-session-manager.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +9 -1
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts +28 -0
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js +161 -27
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +20 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +265 -1
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,85 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.1.21]
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- **Multi-account support**: Login with multiple accounts per provider
|
|
7
|
+
- Use `indusagi login --provider <provider> --account <name>` to add named accounts
|
|
8
|
+
- Use `indusagi login --list` to view all saved accounts
|
|
9
|
+
- Use `indusagi --account <name>` to select which account to use
|
|
10
|
+
- Interactive mode: Select existing accounts or add new ones via `/login`
|
|
11
|
+
- **Claude Sonnet 4.6**: New model added (`claude-sonnet-4-6`) with 200K context, 128K max output, $3/$15 pricing
|
|
12
|
+
- **GLM-5 model**: Fixed endpoint for Z.AI coding subscription (`api.z.ai/api/coding/paas/v4`)
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
- **GPT-5.3 Codex Spark**: Context window updated from 32K to 128K tokens
|
|
16
|
+
- Updated `indusagi` dependency to `0.12.6`
|
|
17
|
+
|
|
18
|
+
### Removed
|
|
19
|
+
- **Google Cloud Code Assist (Gemini CLI)**: OAuth provider removed
|
|
20
|
+
- **Google Antigravity**: OAuth provider and all models removed
|
|
21
|
+
|
|
22
|
+
## [0.1.20]
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
- **kimi-coding**: updated to `indusagi` 0.12.5 with correct official Kimi Code API config
|
|
26
|
+
- Default model changed from `k2p5` → `kimi-for-coding` (official model ID)
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
- Updated `indusagi` dependency to `0.12.5`
|
|
30
|
+
|
|
31
|
+
## [0.1.19]
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
- **kimi-coding garbled responses**: updated to `indusagi` 0.12.4 with correct `openai-completions` API + `api.moonshot.cn/v1` baseUrl
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
- Updated `indusagi` dependency to `0.12.4`
|
|
38
|
+
|
|
39
|
+
## [0.1.18]
|
|
40
|
+
|
|
41
|
+
### Fixed
|
|
42
|
+
- **kimi-coding empty responses**: updated to `indusagi` 0.12.3 which uses `anthropic-messages` API for Kimi Code
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
- Updated `indusagi` dependency to `0.12.3`
|
|
46
|
+
|
|
47
|
+
## [0.1.17]
|
|
48
|
+
|
|
49
|
+
### Fixed
|
|
50
|
+
- **Kimi fetch failed**: updated to `indusagi` 0.12.2 which fixes Kimi API calls
|
|
51
|
+
- Default Kimi model updated to `kimi-k2.5`, Kimi Code to `k2p5`
|
|
52
|
+
- Correct env vars: `MOONSHOT_API_KEY` for kimi, `KIMI_API_KEY` for kimi-coding
|
|
53
|
+
|
|
54
|
+
### Changed
|
|
55
|
+
- Updated `indusagi` dependency to `0.12.2`
|
|
56
|
+
|
|
57
|
+
## [0.1.16]
|
|
58
|
+
|
|
59
|
+
### Fixed
|
|
60
|
+
- **Kimi login**: Removed Kimi from OAuth provider registry — no more `fetch failed` error
|
|
61
|
+
- **TUI /login**: Kimi now appears in the API key section with correct env var hints (`MOONSHOT_API_KEY` / `KIMI_API_KEY`)
|
|
62
|
+
|
|
63
|
+
### Changed
|
|
64
|
+
- Updated `indusagi` dependency to v0.12.1
|
|
65
|
+
|
|
66
|
+
## [0.1.15]
|
|
67
|
+
|
|
68
|
+
### Added
|
|
69
|
+
- **New `login` command**: Authenticate with AI providers using OAuth or API keys
|
|
70
|
+
- `indusagi login` - Show list of available providers
|
|
71
|
+
- `indusagi login --provider <name>` - Login to a specific provider
|
|
72
|
+
- `indusagi login --provider <name> --method oauth|api-key` - Choose auth method
|
|
73
|
+
- Supports Kimi, Anthropic, OpenAI, Google, and more
|
|
74
|
+
- **Kimi (Moonshot AI) Support**: Full integration with Kimi K2.5 and Kimi Code API
|
|
75
|
+
- 5 new Kimi models available
|
|
76
|
+
- OAuth and API key authentication via `/login` command
|
|
77
|
+
- Environment variables: `KIMI_API_KEY`, `KIMICODE_API_KEY`
|
|
78
|
+
|
|
79
|
+
### Changed
|
|
80
|
+
- Updated `indusagi` dependency to v0.12.0 (now includes Kimi provider support)
|
|
81
|
+
- Updated help text with new login command examples and Kimi environment variables
|
|
82
|
+
|
|
3
83
|
## [0.1.14]
|
|
4
84
|
|
|
5
85
|
### Fixed
|
package/dist/cli/args.d.ts
CHANGED
package/dist/cli/args.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGpD,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAEjE,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAE3C,MAAM,WAAW,IAAI;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,8EAA8E;IAC9E,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC,CAAC;CAC5C;AAID,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,aAAa,CAE1E;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAA;CAAE,CAAC,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGpD,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAEjE,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAE3C,MAAM,WAAW,IAAI;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,8EAA8E;IAC9E,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC,CAAC;CAC5C;AAID,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,aAAa,CAE1E;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAA;CAAE,CAAC,GAAG,IAAI,CA+H5G;AAED,wBAAgB,SAAS,IAAI,IAAI,CA8IhC"}
|
package/dist/cli/args.js
CHANGED
|
@@ -37,6 +37,9 @@ export function parseArgs(args, extensionFlags) {
|
|
|
37
37
|
else if (arg === "--provider" && i + 1 < args.length) {
|
|
38
38
|
result.provider = args[++i];
|
|
39
39
|
}
|
|
40
|
+
else if (arg === "--account" && i + 1 < args.length) {
|
|
41
|
+
result.account = args[++i];
|
|
42
|
+
}
|
|
40
43
|
else if (arg === "--model" && i + 1 < args.length) {
|
|
41
44
|
result.model = args[++i];
|
|
42
45
|
}
|
|
@@ -169,6 +172,8 @@ ${chalk.bold("Usage:")}
|
|
|
169
172
|
${APP_NAME} [options] [@files...] [messages...]
|
|
170
173
|
|
|
171
174
|
${chalk.bold("Commands:")}
|
|
175
|
+
${APP_NAME} login [--provider <name>] Authenticate with an AI provider (OAuth or API key)
|
|
176
|
+
[--method oauth|api-key]
|
|
172
177
|
${APP_NAME} install <source> [-l] Install extension source and add to settings
|
|
173
178
|
${APP_NAME} remove <source> [-l] Remove extension source from settings
|
|
174
179
|
${APP_NAME} update [source] Update installed extensions (skips pinned sources)
|
|
@@ -177,6 +182,7 @@ ${chalk.bold("Commands:")}
|
|
|
177
182
|
|
|
178
183
|
${chalk.bold("Options:")}
|
|
179
184
|
--provider <name> Provider name (default: google)
|
|
185
|
+
--account <name> Account name for multi-account providers (default: default)
|
|
180
186
|
--model <id> Model ID (default: gemini-2.5-flash)
|
|
181
187
|
--api-key <key> API key (defaults to env vars)
|
|
182
188
|
--system-prompt <text> System prompt (default: coding assistant prompt)
|
|
@@ -253,6 +259,17 @@ ${chalk.bold("Examples:")}
|
|
|
253
259
|
${APP_NAME} --export ~/${CONFIG_DIR_NAME}/agent/sessions/--path--/session.jsonl
|
|
254
260
|
${APP_NAME} --export session.jsonl output.html
|
|
255
261
|
|
|
262
|
+
# Authentication / Login
|
|
263
|
+
${APP_NAME} login # Show available providers for login
|
|
264
|
+
${APP_NAME} login --provider kimi # Login to Kimi with API key
|
|
265
|
+
${APP_NAME} login --provider kimi-coding # Login to Kimi Code with API key
|
|
266
|
+
${APP_NAME} login --provider anthropic # Login to Anthropic with OAuth
|
|
267
|
+
${APP_NAME} login --provider openai # Login to OpenAI with API key
|
|
268
|
+
${APP_NAME} login --provider minimax --account prod # Login to MiniMax (prod account)
|
|
269
|
+
${APP_NAME} login --provider minimax --account dev # Login to MiniMax (dev account)
|
|
270
|
+
${APP_NAME} login --list # List all saved accounts
|
|
271
|
+
${APP_NAME} logout --provider minimax --account dev # Logout specific account
|
|
272
|
+
|
|
256
273
|
${chalk.bold("Environment Variables:")}
|
|
257
274
|
ANTHROPIC_AINDUSAGI_KEY - Anthropic Claude API key
|
|
258
275
|
ANTHROPIC_OAUTH_TOKEN - Anthropic OAuth token (alternative to API key)
|
|
@@ -271,6 +288,8 @@ ${chalk.bold("Environment Variables:")}
|
|
|
271
288
|
ZAI_AINDUSAGI_KEY - ZAI API key
|
|
272
289
|
MISTRAL_AINDUSAGI_KEY - Mistral API key
|
|
273
290
|
MINIMAX_AINDUSAGI_KEY - MiniMax API key
|
|
291
|
+
KIMI_AINDUSAGI_KEY - Kimi (Moonshot AI) API key
|
|
292
|
+
KIMICODE_AINDUSAGI_KEY - Kimi Code (subscription) API key
|
|
274
293
|
AWS_PROFILE - AWS profile for Amazon Bedrock
|
|
275
294
|
AWS_ACCESS_KEY_ID - AWS access key for Amazon Bedrock
|
|
276
295
|
AWS_SECRET_ACCESS_KEY - AWS secret key for Amazon Bedrock
|
package/dist/cli/args.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAiB,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Login command handler for AI provider authentication
|
|
3
|
+
* Supports OAuth and API key-based authentication
|
|
4
|
+
*
|
|
5
|
+
* MULTI-ACCOUNT SUPPORT: Each provider can have multiple named accounts.
|
|
6
|
+
*
|
|
7
|
+
* Pattern matched with openclaw implementation:
|
|
8
|
+
* - Check for environment variables (KIMI_API_KEY, MOONSHOT_API_KEY, etc.)
|
|
9
|
+
* - Show info/help URL
|
|
10
|
+
* - Prompt for API key input
|
|
11
|
+
* - Store in auth storage with account name
|
|
12
|
+
*/
|
|
13
|
+
export interface LoginOptions {
|
|
14
|
+
provider?: string;
|
|
15
|
+
account?: string;
|
|
16
|
+
list?: boolean;
|
|
17
|
+
all?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare function handleLoginCommand(args: string[]): Promise<boolean>;
|
|
20
|
+
//# sourceMappingURL=login-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login-handler.d.ts","sourceRoot":"","sources":["../../src/cli/login-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAQH,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;CACd;AA2BD,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CA8BzE"}
|
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Login command handler for AI provider authentication
|
|
3
|
+
* Supports OAuth and API key-based authentication
|
|
4
|
+
*
|
|
5
|
+
* MULTI-ACCOUNT SUPPORT: Each provider can have multiple named accounts.
|
|
6
|
+
*
|
|
7
|
+
* Pattern matched with openclaw implementation:
|
|
8
|
+
* - Check for environment variables (KIMI_API_KEY, MOONSHOT_API_KEY, etc.)
|
|
9
|
+
* - Show info/help URL
|
|
10
|
+
* - Prompt for API key input
|
|
11
|
+
* - Store in auth storage with account name
|
|
12
|
+
*/
|
|
13
|
+
import { getEnvApiKey, getOAuthProviders } from "indusagi/ai";
|
|
14
|
+
import chalk from "chalk";
|
|
15
|
+
import { createInterface } from "readline";
|
|
16
|
+
import { AuthStorage } from "../core/auth-storage.js";
|
|
17
|
+
import { getAgentDir } from "../config.js";
|
|
18
|
+
function parseLoginCommand(args) {
|
|
19
|
+
const [command, ...rest] = args;
|
|
20
|
+
if (command !== "login" && command !== "logout") {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
const options = {};
|
|
24
|
+
const isLogout = command === "logout";
|
|
25
|
+
for (let i = 0; i < rest.length; i++) {
|
|
26
|
+
const arg = rest[i];
|
|
27
|
+
if (arg === "--provider" && i + 1 < rest.length) {
|
|
28
|
+
options.provider = rest[++i];
|
|
29
|
+
}
|
|
30
|
+
else if (arg === "--account" && i + 1 < rest.length) {
|
|
31
|
+
options.account = rest[++i];
|
|
32
|
+
}
|
|
33
|
+
else if (arg === "--list") {
|
|
34
|
+
options.list = true;
|
|
35
|
+
}
|
|
36
|
+
else if (arg === "--all" && isLogout) {
|
|
37
|
+
options.all = true;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return options;
|
|
41
|
+
}
|
|
42
|
+
export async function handleLoginCommand(args) {
|
|
43
|
+
const options = parseLoginCommand(args);
|
|
44
|
+
if (!options) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
const agentDir = getAgentDir();
|
|
48
|
+
const authStorage = new AuthStorage(agentDir);
|
|
49
|
+
// Handle --list flag
|
|
50
|
+
if (options.list) {
|
|
51
|
+
await listAccounts(authStorage);
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
// If provider not specified, show list
|
|
55
|
+
if (!options.provider) {
|
|
56
|
+
await showProviderSelection(authStorage);
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
// Handle logout
|
|
60
|
+
if (args[0] === "logout") {
|
|
61
|
+
await logoutFromProvider(authStorage, options.provider, options.account, options.all);
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
// Login to specific provider
|
|
65
|
+
await loginToProvider(authStorage, options.provider, options.account);
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
async function listAccounts(authStorage) {
|
|
69
|
+
console.log(chalk.bold("\n🔐 Saved Accounts:\n"));
|
|
70
|
+
const providers = authStorage.list();
|
|
71
|
+
if (providers.length === 0) {
|
|
72
|
+
console.log(chalk.dim("No saved accounts. Use 'indusagi login --provider <provider>' to add accounts.\n"));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
for (const provider of providers) {
|
|
76
|
+
const accounts = authStorage.getAccounts(provider);
|
|
77
|
+
const defaultAccount = authStorage.getDefaultAccount(provider);
|
|
78
|
+
console.log(chalk.cyan(`${provider} (${accounts.length} account${accounts.length !== 1 ? 's' : ''}):`));
|
|
79
|
+
for (const { accountId, credential } of accounts) {
|
|
80
|
+
const isDefault = accountId === defaultAccount;
|
|
81
|
+
const defaultMarker = isDefault ? chalk.green(" [default]") : "";
|
|
82
|
+
const type = credential.type === "oauth" ? "OAuth" : "API key";
|
|
83
|
+
const name = credential.accountName || accountId;
|
|
84
|
+
let status = "✓";
|
|
85
|
+
if (credential.type === "oauth") {
|
|
86
|
+
const expired = Date.now() >= credential.expires;
|
|
87
|
+
status = expired ? chalk.yellow("⚠ expired") : chalk.green("✓");
|
|
88
|
+
}
|
|
89
|
+
console.log(` ${status} ${name}${defaultMarker} (${type})`);
|
|
90
|
+
}
|
|
91
|
+
console.log();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async function showProviderSelection(authStorage) {
|
|
95
|
+
// Get OAuth providers
|
|
96
|
+
const oauthProviders = getOAuthProviders().map(p => ({
|
|
97
|
+
id: p.id,
|
|
98
|
+
name: p.name,
|
|
99
|
+
auth: "OAuth",
|
|
100
|
+
}));
|
|
101
|
+
// API key providers
|
|
102
|
+
const apiKeyProviders = [
|
|
103
|
+
{ id: "kimi", name: "Kimi (Moonshot AI)", auth: "API key" },
|
|
104
|
+
{ id: "kimi-coding", name: "Kimi Code (Moonshot - Subscription)", auth: "API key" },
|
|
105
|
+
{ id: "anthropic", name: "Anthropic (Claude)", auth: "API key" },
|
|
106
|
+
{ id: "openai", name: "OpenAI", auth: "API key" },
|
|
107
|
+
{ id: "google", name: "Google (Gemini)", auth: "API key" },
|
|
108
|
+
{ id: "groq", name: "Groq", auth: "API key" },
|
|
109
|
+
{ id: "cerebras", name: "Cerebras", auth: "API key" },
|
|
110
|
+
{ id: "xai", name: "xAI (Grok)", auth: "API key" },
|
|
111
|
+
{ id: "openrouter", name: "OpenRouter", auth: "API key" },
|
|
112
|
+
{ id: "vercel-ai-gateway", name: "Vercel AI Gateway", auth: "API key" },
|
|
113
|
+
{ id: "zai", name: "Z.AI (GLM)", auth: "API key" },
|
|
114
|
+
{ id: "mistral", name: "Mistral", auth: "API key" },
|
|
115
|
+
{ id: "minimax", name: "MiniMax", auth: "API key" },
|
|
116
|
+
{ id: "minimax-cn", name: "MiniMax (China)", auth: "API key" },
|
|
117
|
+
{ id: "opencode", name: "OpenCode Zen", auth: "API key" },
|
|
118
|
+
];
|
|
119
|
+
console.log(chalk.bold("\n🔐 Available Providers for Authentication\n"));
|
|
120
|
+
console.log(chalk.dim("OAuth Providers:"));
|
|
121
|
+
oauthProviders.forEach((p, idx) => {
|
|
122
|
+
const accountCount = authStorage.getAccounts(p.id).length;
|
|
123
|
+
const accountInfo = accountCount > 0 ? chalk.green(` (${accountCount} saved)`) : "";
|
|
124
|
+
console.log(` ${idx + 1}. ${p.name} ${chalk.dim(`(${p.auth})`)}${accountInfo}`);
|
|
125
|
+
});
|
|
126
|
+
console.log(chalk.dim("\nAPI Key Providers:"));
|
|
127
|
+
apiKeyProviders.forEach((p, idx) => {
|
|
128
|
+
const accountCount = authStorage.getAccounts(p.id).length;
|
|
129
|
+
const accountInfo = accountCount > 0 ? chalk.green(` (${accountCount} saved)`) : "";
|
|
130
|
+
console.log(` ${oauthProviders.length + idx + 1}. ${p.name} ${chalk.dim(`(${p.auth})`)}${accountInfo}`);
|
|
131
|
+
});
|
|
132
|
+
console.log("\n" + chalk.dim("Run: indusagi login --provider <provider-id> [--account <name>]"));
|
|
133
|
+
console.log(chalk.dim("Example: indusagi login --provider minimax --account production\n"));
|
|
134
|
+
// Show examples
|
|
135
|
+
console.log(chalk.bold("Examples:"));
|
|
136
|
+
console.log(` ${chalk.cyan("indusagi login --provider openai-codex --account personal")} ${chalk.dim("# Login to ChatGPT (personal)")}`);
|
|
137
|
+
console.log(` ${chalk.cyan("indusagi login --provider openai-codex --account work")} ${chalk.dim("# Login to ChatGPT (work)")}`);
|
|
138
|
+
console.log(` ${chalk.cyan("indusagi login --provider minimax --account prod")} ${chalk.dim("# Add MiniMax API key (prod)")}`);
|
|
139
|
+
console.log(` ${chalk.cyan("indusagi login --provider minimax --account dev")} ${chalk.dim("# Add MiniMax API key (dev)")}`);
|
|
140
|
+
console.log(` ${chalk.cyan("indusagi login --list")} ${chalk.dim("# List all saved accounts")}`);
|
|
141
|
+
console.log(` ${chalk.cyan("indusagi logout --provider openai-codex --account work")} ${chalk.dim("# Logout specific account")}\n`);
|
|
142
|
+
}
|
|
143
|
+
async function loginToProvider(authStorage, provider, accountId) {
|
|
144
|
+
// Check if this is an OAuth provider
|
|
145
|
+
const oauthProviders = getOAuthProviders();
|
|
146
|
+
const oauthProvider = oauthProviders.find(p => p.id === provider);
|
|
147
|
+
// Generate account name if not provided
|
|
148
|
+
const targetAccountId = accountId || "default";
|
|
149
|
+
const existingAccounts = authStorage.getAccounts(provider);
|
|
150
|
+
// If no account specified and accounts exist, ask if user wants to add new or use existing
|
|
151
|
+
if (!accountId && existingAccounts.length > 0) {
|
|
152
|
+
console.log(chalk.yellow(`\n⚠️ Provider '${provider}' already has ${existingAccounts.length} saved account(s):`));
|
|
153
|
+
for (const { accountId, credential } of existingAccounts) {
|
|
154
|
+
const name = credential.accountName || accountId;
|
|
155
|
+
const isDefault = accountId === authStorage.getDefaultAccount(provider);
|
|
156
|
+
console.log(` - ${name}${isDefault ? " [default]" : ""}`);
|
|
157
|
+
}
|
|
158
|
+
const choice = await promptChoice("What would you like to do?", ["Use existing account", "Add new account"]);
|
|
159
|
+
if (choice === "Use existing account") {
|
|
160
|
+
const selected = await promptChoice("Select account:", existingAccounts.map(a => a.credential.accountName || a.accountId));
|
|
161
|
+
const selectedAccount = existingAccounts.find(a => (a.credential.accountName || a.accountId) === selected);
|
|
162
|
+
if (selectedAccount) {
|
|
163
|
+
authStorage.setDefaultAccount(provider, selectedAccount.accountId);
|
|
164
|
+
console.log(chalk.green.bold(`\n✅ Switched to account: ${selected}\n`));
|
|
165
|
+
}
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
// User wants to add new account - prompt for name
|
|
169
|
+
const newName = await promptInput("Enter new account name (e.g., 'work', 'personal')");
|
|
170
|
+
if (!newName || newName.trim() === "") {
|
|
171
|
+
console.error(chalk.red("\n❌ Account name is required\n"));
|
|
172
|
+
process.exit(1);
|
|
173
|
+
}
|
|
174
|
+
// Check if name already exists
|
|
175
|
+
const nameExists = existingAccounts.some(a => (a.credential.accountName || a.accountId) === newName.trim());
|
|
176
|
+
if (nameExists) {
|
|
177
|
+
console.error(chalk.red(`\n❌ Account '${newName}' already exists for ${provider}\n`));
|
|
178
|
+
process.exit(1);
|
|
179
|
+
}
|
|
180
|
+
accountId = newName.trim();
|
|
181
|
+
}
|
|
182
|
+
console.log(chalk.bold(`\n🔐 Logging in to ${provider}${accountId ? ` [${accountId}]` : ""}...\n`));
|
|
183
|
+
// Handle OAuth login
|
|
184
|
+
if (oauthProvider) {
|
|
185
|
+
console.log(chalk.dim(`Starting OAuth flow for ${oauthProvider.name}...`));
|
|
186
|
+
console.log(chalk.dim("A browser window should open. Complete login to finish.\n"));
|
|
187
|
+
try {
|
|
188
|
+
await authStorage.login(provider, {
|
|
189
|
+
onAuth: (info) => {
|
|
190
|
+
console.log(chalk.dim(`Opening: ${info.url}`));
|
|
191
|
+
if (info.instructions) {
|
|
192
|
+
console.log(chalk.dim(info.instructions));
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
onPrompt: async (prompt) => {
|
|
196
|
+
return promptInput(prompt.message);
|
|
197
|
+
},
|
|
198
|
+
onProgress: (msg) => {
|
|
199
|
+
console.log(chalk.dim(msg));
|
|
200
|
+
},
|
|
201
|
+
}, targetAccountId, accountId);
|
|
202
|
+
console.log(chalk.green.bold(`\n✅ Login successful! Account: ${accountId || "default"}\n`));
|
|
203
|
+
console.log(chalk.dim(`Use: indusagi --provider ${provider} --account ${accountId || "default"} [options]\n`));
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
console.error(chalk.red(`\n❌ Login failed: ${error instanceof Error ? error.message : error}\n`));
|
|
207
|
+
process.exit(1);
|
|
208
|
+
}
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
// Handle API key login
|
|
212
|
+
const envKey = getEnvApiKey(provider);
|
|
213
|
+
// Get provider info
|
|
214
|
+
const providerInfo = getProviderInfo(provider);
|
|
215
|
+
if (!providerInfo) {
|
|
216
|
+
console.error(chalk.red(`Unknown provider: ${provider}`));
|
|
217
|
+
process.exit(1);
|
|
218
|
+
}
|
|
219
|
+
// Show help message with URL
|
|
220
|
+
if (providerInfo.helpUrl) {
|
|
221
|
+
await prompter.note(`Get your ${providerInfo.name} API key at:\n${providerInfo.helpUrl}`, providerInfo.name);
|
|
222
|
+
}
|
|
223
|
+
// Check for existing env variable
|
|
224
|
+
if (envKey) {
|
|
225
|
+
const useExisting = await promptChoice(`Use existing ${providerInfo.envVar} (from environment)?`, ["Yes", "No, enter a new key"]);
|
|
226
|
+
if (useExisting === "Yes") {
|
|
227
|
+
authStorage.set(provider, targetAccountId, {
|
|
228
|
+
type: "api_key",
|
|
229
|
+
key: envKey,
|
|
230
|
+
accountId: targetAccountId,
|
|
231
|
+
accountName: accountId || "Default",
|
|
232
|
+
});
|
|
233
|
+
console.log(chalk.green.bold(`\n✅ Login successful! Account: ${accountId || "default"}\n`));
|
|
234
|
+
console.log(chalk.dim(`Using ${providerInfo.envVar} from environment`));
|
|
235
|
+
console.log(chalk.dim(`Use: indusagi --provider ${provider} --account ${accountId || "default"} [options]\n`));
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// Prompt for API key
|
|
240
|
+
const apiKey = await promptInput(`Enter ${providerInfo.name} API key`);
|
|
241
|
+
if (!apiKey || apiKey.trim() === "") {
|
|
242
|
+
console.error(chalk.red("\n❌ API key is required\n"));
|
|
243
|
+
process.exit(1);
|
|
244
|
+
}
|
|
245
|
+
authStorage.set(provider, targetAccountId, {
|
|
246
|
+
type: "api_key",
|
|
247
|
+
key: apiKey.trim(),
|
|
248
|
+
accountId: targetAccountId,
|
|
249
|
+
accountName: accountId || "Default",
|
|
250
|
+
});
|
|
251
|
+
console.log(chalk.green.bold(`\n✅ Login successful! Account: ${accountId || "default"}\n`));
|
|
252
|
+
console.log(chalk.dim(`API key saved for ${provider}/${accountId || "default"}`));
|
|
253
|
+
console.log(chalk.dim(`Use: indusagi --provider ${provider} --account ${accountId || "default"} [options]\n`));
|
|
254
|
+
}
|
|
255
|
+
async function logoutFromProvider(authStorage, provider, accountId, all) {
|
|
256
|
+
if (all) {
|
|
257
|
+
authStorage.logout(provider);
|
|
258
|
+
console.log(chalk.green.bold(`\n✅ Logged out all accounts for: ${provider}\n`));
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
const accounts = authStorage.getAccounts(provider);
|
|
262
|
+
if (accounts.length === 0) {
|
|
263
|
+
console.log(chalk.yellow(`\n⚠️ No accounts found for: ${provider}\n`));
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
// If specific account provided
|
|
267
|
+
if (accountId) {
|
|
268
|
+
authStorage.logout(provider, accountId);
|
|
269
|
+
console.log(chalk.green.bold(`\n✅ Logged out: ${provider}/${accountId}\n`));
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
// If multiple accounts, ask which one
|
|
273
|
+
if (accounts.length > 1) {
|
|
274
|
+
const selected = await promptChoice("Select account to logout:", [...accounts.map(a => a.credential.accountName || a.accountId), "All accounts"]);
|
|
275
|
+
if (selected === "All accounts") {
|
|
276
|
+
authStorage.logout(provider);
|
|
277
|
+
console.log(chalk.green.bold(`\n✅ Logged out all accounts for: ${provider}\n`));
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
const selectedAccount = accounts.find(a => (a.credential.accountName || a.accountId) === selected);
|
|
281
|
+
if (selectedAccount) {
|
|
282
|
+
authStorage.logout(provider, selectedAccount.accountId);
|
|
283
|
+
console.log(chalk.green.bold(`\n✅ Logged out: ${provider}/${selected}\n`));
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
// Single account - logout it
|
|
289
|
+
const singleAccount = accounts[0];
|
|
290
|
+
authStorage.logout(provider, singleAccount.accountId);
|
|
291
|
+
console.log(chalk.green.bold(`\n✅ Logged out: ${provider}/${singleAccount.credential.accountName || singleAccount.accountId}\n`));
|
|
292
|
+
}
|
|
293
|
+
function getProviderInfo(provider) {
|
|
294
|
+
const providers = {
|
|
295
|
+
kimi: {
|
|
296
|
+
name: "Kimi (Moonshot AI)",
|
|
297
|
+
envVar: "MOONSHOT_API_KEY",
|
|
298
|
+
helpUrl: "https://www.moonshot.cn/",
|
|
299
|
+
},
|
|
300
|
+
"kimi-coding": {
|
|
301
|
+
name: "Kimi Code (Moonshot - Subscription)",
|
|
302
|
+
envVar: "KIMI_API_KEY",
|
|
303
|
+
helpUrl: "https://www.kimi.com/code/en",
|
|
304
|
+
},
|
|
305
|
+
moonshot: {
|
|
306
|
+
name: "Moonshot AI (Kimi)",
|
|
307
|
+
envVar: "MOONSHOT_API_KEY",
|
|
308
|
+
helpUrl: "https://www.moonshot.cn/",
|
|
309
|
+
},
|
|
310
|
+
anthropic: {
|
|
311
|
+
name: "Anthropic (Claude)",
|
|
312
|
+
envVar: "ANTHROPIC_API_KEY",
|
|
313
|
+
helpUrl: "https://console.anthropic.com/",
|
|
314
|
+
},
|
|
315
|
+
openai: {
|
|
316
|
+
name: "OpenAI",
|
|
317
|
+
envVar: "OPENAI_API_KEY",
|
|
318
|
+
helpUrl: "https://platform.openai.com/api-keys",
|
|
319
|
+
},
|
|
320
|
+
google: {
|
|
321
|
+
name: "Google (Gemini)",
|
|
322
|
+
envVar: "GEMINI_API_KEY",
|
|
323
|
+
helpUrl: "https://aistudio.google.com/app/apikey",
|
|
324
|
+
},
|
|
325
|
+
groq: {
|
|
326
|
+
name: "Groq",
|
|
327
|
+
envVar: "GROQ_API_KEY",
|
|
328
|
+
helpUrl: "https://console.groq.com/keys",
|
|
329
|
+
},
|
|
330
|
+
cerebras: {
|
|
331
|
+
name: "Cerebras",
|
|
332
|
+
envVar: "CEREBRAS_API_KEY",
|
|
333
|
+
helpUrl: "https://cloud.cerebras.ai/",
|
|
334
|
+
},
|
|
335
|
+
xai: {
|
|
336
|
+
name: "xAI (Grok)",
|
|
337
|
+
envVar: "XAI_API_KEY",
|
|
338
|
+
helpUrl: "https://x.ai/api",
|
|
339
|
+
},
|
|
340
|
+
openrouter: {
|
|
341
|
+
name: "OpenRouter",
|
|
342
|
+
envVar: "OPENROUTER_API_KEY",
|
|
343
|
+
helpUrl: "https://openrouter.ai/keys",
|
|
344
|
+
},
|
|
345
|
+
"vercel-ai-gateway": {
|
|
346
|
+
name: "Vercel AI Gateway",
|
|
347
|
+
envVar: "AI_GATEWAY_API_KEY",
|
|
348
|
+
helpUrl: "https://vercel.com/docs/ai-gateway",
|
|
349
|
+
},
|
|
350
|
+
zai: {
|
|
351
|
+
name: "Z.AI (GLM)",
|
|
352
|
+
envVar: "ZAI_API_KEY",
|
|
353
|
+
helpUrl: "https://api.z.ai/",
|
|
354
|
+
},
|
|
355
|
+
mistral: {
|
|
356
|
+
name: "Mistral",
|
|
357
|
+
envVar: "MISTRAL_API_KEY",
|
|
358
|
+
helpUrl: "https://console.mistral.ai/",
|
|
359
|
+
},
|
|
360
|
+
minimax: {
|
|
361
|
+
name: "MiniMax",
|
|
362
|
+
envVar: "MINIMAX_API_KEY",
|
|
363
|
+
helpUrl: "https://www.minimaxi.com/",
|
|
364
|
+
},
|
|
365
|
+
"minimax-cn": {
|
|
366
|
+
name: "MiniMax (China)",
|
|
367
|
+
envVar: "MINIMAX_CN_API_KEY",
|
|
368
|
+
helpUrl: "https://www.minimaxi.com/",
|
|
369
|
+
},
|
|
370
|
+
opencode: {
|
|
371
|
+
name: "OpenCode Zen",
|
|
372
|
+
envVar: "OPENCODE_API_KEY",
|
|
373
|
+
helpUrl: "https://opencode.ai/",
|
|
374
|
+
},
|
|
375
|
+
};
|
|
376
|
+
return providers[provider];
|
|
377
|
+
}
|
|
378
|
+
const prompter = {
|
|
379
|
+
note(message, title) {
|
|
380
|
+
console.log(`\n${chalk.bold(title)}`);
|
|
381
|
+
console.log(chalk.dim(message) + "\n");
|
|
382
|
+
},
|
|
383
|
+
};
|
|
384
|
+
function promptChoice(question, options) {
|
|
385
|
+
return new Promise((resolve) => {
|
|
386
|
+
const rl = createInterface({
|
|
387
|
+
input: process.stdin,
|
|
388
|
+
output: process.stdout,
|
|
389
|
+
});
|
|
390
|
+
console.log(chalk.bold(`\n? ${question}`));
|
|
391
|
+
options.forEach((opt, idx) => {
|
|
392
|
+
console.log(` ${idx + 1}. ${opt}`);
|
|
393
|
+
});
|
|
394
|
+
rl.question(chalk.bold("Select (1-" + options.length + "): "), (answer) => {
|
|
395
|
+
rl.close();
|
|
396
|
+
const idx = parseInt(answer, 10) - 1;
|
|
397
|
+
resolve(options[idx] || options[0]);
|
|
398
|
+
});
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
function promptInput(question) {
|
|
402
|
+
return new Promise((resolve) => {
|
|
403
|
+
const rl = createInterface({
|
|
404
|
+
input: process.stdin,
|
|
405
|
+
output: process.stdout,
|
|
406
|
+
});
|
|
407
|
+
rl.question(chalk.bold(`\n? ${question}: `), (answer) => {
|
|
408
|
+
rl.close();
|
|
409
|
+
resolve(answer.trim());
|
|
410
|
+
});
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
//# sourceMappingURL=login-handler.js.map
|