@xopcai/xopc 0.0.102 → 0.0.103
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 +1 -1
- package/README.zh-CN.md +1 -1
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/feishu/src/transport/webhook/monitor.js +2 -2
- package/dist/extensions/feishu/src/transport/webhook/monitor.js.map +1 -1
- package/dist/extensions/telegram/src/send-options.js +8 -5
- package/dist/extensions/telegram/src/send-options.js.map +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agents-DQ0mQxIA.js → agents-BwXkia_W.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-Uv4kOmDE.js → apps-page-C5RmwmTT.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-settings-BEtP53V6.js → channels-settings-tlOTdaXw.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-status-swr-CxTtS1hI.js → channels-status-swr-D4XjqwqC.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-api-CznlPIZT.js → cron-api-DcmfGuj0.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-page-Dx6dE3eD.js → cron-page-CijJ4G6F.js} +1 -1
- package/dist/gateway/static/root/assets/{dist-DH4IuRV0.js → dist-CWm8hTXZ.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-BNkhvRQW.js → extension-debug-page-BzYgTkS9.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-CcIGQah2.js → extension-page-BmTZH6gL.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-DuDCSb3J.js → extension-settings-page-CyJk_G64.js} +1 -1
- package/dist/gateway/static/root/assets/{fetch-drJUxxKP.js → fetch-CMoWY2Si.js} +1 -1
- package/dist/gateway/static/root/assets/{field-primitives-BUwUiDf5.js → field-primitives-C4GpxsDo.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-config-api-BjFW1cl-.js → heartbeat-config-api-CLD0Gpi3.js} +1 -1
- package/dist/gateway/static/root/assets/index-0HmunJW9.js +4845 -0
- package/dist/gateway/static/root/assets/index-Bk75Phrd.css +1 -0
- package/dist/gateway/static/root/assets/{logs-page-CiG0m81R.js → logs-page-BjdQjHwk.js} +1 -1
- package/dist/gateway/static/root/assets/{note-detail-page-DG3DVFTf.js → note-detail-page-8Er4197b.js} +1 -1
- package/dist/gateway/static/root/assets/{note-time-DjlllCF3.js → note-time-CF3vf1jm.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-page-D40ZpS0Y.js → notes-page-BBnTh0uI.js} +1 -1
- package/dist/gateway/static/root/assets/{sessions-page-BvtdbmW8.js → sessions-page-B0riYK7j.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-advanced-gate-BQamRjkV.js → settings-advanced-gate-DiP_WHu_.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-C3_sEFfD.js → settings-form-section-C7qA7y0J.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-D972_jaS.js → settings-page-1ZPhcCZ9.js} +2 -2
- package/dist/gateway/static/root/assets/share-preview-page-Tvr5Mtq5.js +2 -0
- package/dist/gateway/static/root/assets/{skills-page-QwFCB4yV.js → skills-page-BQ1hllKD.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-B6KXPHgK.js → theme-store-HTvJlFLL.js} +1 -1
- package/dist/gateway/static/root/assets/url-F3_D_6zZ.js +3 -0
- package/dist/gateway/static/root/assets/{utils-DCm11_KW.js → utils-CPr3FBh2.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-CywiB7Dw.js → voice-api-key-field-BkbDl6dH.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-page.utils-g57BRfEd.js → workflow-page.utils-CeBkAjP7.js} +1 -1
- package/dist/gateway/static/root/assets/{workflows-page-Be7l_SWw.js → workflows-page-D059ysoF.js} +1 -1
- package/dist/gateway/static/root/index.html +5 -5
- package/dist/package.js +1 -1
- package/dist/src/agent/inbound/attachment-pipeline.js +2 -2
- package/dist/src/agent/inbound/attachment-pipeline.js.map +1 -1
- package/dist/src/agent/tools/send-media.js +1 -2
- package/dist/src/agent/tools/send-media.js.map +1 -1
- package/dist/src/auth/credentials.d.ts +7 -0
- package/dist/src/auth/credentials.js +35 -2
- package/dist/src/auth/credentials.js.map +1 -1
- package/dist/src/auth/index.d.ts +1 -1
- package/dist/src/auth/index.js.map +1 -1
- package/dist/src/auth/oauth/github-copilot.d.ts +1 -1
- package/dist/src/auth/oauth/google-antigravity.d.ts +1 -3
- package/dist/src/auth/oauth/google-antigravity.js +1 -1
- package/dist/src/auth/oauth/google-gemini-cli.d.ts +1 -3
- package/dist/src/auth/oauth/google-gemini-cli.js +1 -1
- package/dist/src/auth/oauth/{vendor-pi-google → google-oauth}/google-antigravity.js +3 -5
- package/dist/src/auth/oauth/google-oauth/google-antigravity.js.map +1 -0
- package/dist/src/auth/oauth/{vendor-pi-google → google-oauth}/google-gemini-cli.js +4 -5
- package/dist/src/auth/oauth/google-oauth/google-gemini-cli.js.map +1 -0
- package/dist/src/auth/oauth/{vendor-pi-google → google-oauth}/oauth-page.js +12 -4
- package/dist/src/auth/oauth/google-oauth/oauth-page.js.map +1 -0
- package/dist/src/auth/oauth/{vendor-pi-google → google-oauth}/pkce.d.ts +1 -1
- package/dist/src/auth/oauth/{vendor-pi-google → google-oauth}/pkce.js +2 -2
- package/dist/src/auth/oauth/google-oauth/pkce.js.map +1 -0
- package/dist/src/auth/oauth/index.js +2 -2
- package/dist/src/auth/oauth/kimi-coding.d.ts +1 -1
- package/dist/src/auth/oauth/kimi-coding.js +1 -1
- package/dist/src/auth/oauth/kimi-coding.js.map +1 -1
- package/dist/src/auth/oauth/minimax-cn.js +1 -1
- package/dist/src/auth/oauth/minimax-cn.js.map +1 -1
- package/dist/src/auth/oauth/minimax.js +1 -1
- package/dist/src/auth/oauth/minimax.js.map +1 -1
- package/dist/src/auth/oauth/openai-codex.d.ts +7 -2
- package/dist/src/auth/oauth/openai-codex.js +318 -1
- package/dist/src/auth/oauth/openai-codex.js.map +1 -0
- package/dist/src/auth/profiles/store.js +3 -2
- package/dist/src/auth/profiles/store.js.map +1 -1
- package/dist/src/channels/attachments/attachment-classifiers.d.ts +1 -0
- package/dist/src/channels/attachments/attachment-classifiers.js +13 -2
- package/dist/src/channels/attachments/attachment-classifiers.js.map +1 -1
- package/dist/src/chat-commands/builtins/model.js +2 -2
- package/dist/src/chat-commands/builtins/model.js.map +1 -1
- package/dist/src/cli/command-manifest.js +1 -1
- package/dist/src/cli/command-manifest.js.map +1 -1
- package/dist/src/cli/commands/auth.js +39 -51
- package/dist/src/cli/commands/auth.js.map +1 -1
- package/dist/src/cli/commands/models.js +189 -54
- package/dist/src/cli/commands/models.js.map +1 -1
- package/dist/src/cli/commands/onboard/model.d.ts +1 -4
- package/dist/src/cli/commands/onboard/model.js +253 -183
- package/dist/src/cli/commands/onboard/model.js.map +1 -1
- package/dist/src/cli/utils/oauth-login.d.ts +17 -0
- package/dist/src/cli/utils/oauth-login.js +93 -0
- package/dist/src/cli/utils/oauth-login.js.map +1 -0
- package/dist/src/cli/utils/oauth-providers.js +2 -2
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/oauth-async.js +2 -2
- package/dist/src/gateway/hono/oauth.js +2 -2
- package/dist/src/gateway/hono/routes/models.js +25 -5
- package/dist/src/gateway/hono/routes/models.js.map +1 -1
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/media/store.js +3 -0
- package/dist/src/media/store.js.map +1 -1
- package/dist/src/notes/service.js +1 -1
- package/dist/src/notes/service.js.map +1 -1
- package/dist/src/providers/index.d.ts +3 -3
- package/dist/src/providers/index.js +23 -15
- package/dist/src/providers/index.js.map +1 -1
- package/dist/src/providers/presentation.d.ts +34 -0
- package/dist/src/providers/presentation.js +162 -0
- package/dist/src/providers/presentation.js.map +1 -0
- package/package.json +1 -1
- package/dist/gateway/static/root/assets/index-DKgHC1Ta.js +0 -4840
- package/dist/gateway/static/root/assets/index-DjNDHzwG.css +0 -1
- package/dist/gateway/static/root/assets/share-preview-page-CKCTMo0_.js +0 -2
- package/dist/gateway/static/root/assets/url-q28QhI7l.js +0 -3
- package/dist/src/auth/oauth/vendor-pi-google/google-antigravity.js.map +0 -1
- package/dist/src/auth/oauth/vendor-pi-google/google-gemini-cli.js.map +0 -1
- package/dist/src/auth/oauth/vendor-pi-google/oauth-page.js.map +0 -1
- package/dist/src/auth/oauth/vendor-pi-google/pkce.js.map +0 -1
- /package/dist/src/auth/oauth/{vendor-pi-google → google-oauth}/google-antigravity.d.ts +0 -0
- /package/dist/src/auth/oauth/{vendor-pi-google → google-oauth}/google-gemini-cli.d.ts +0 -0
- /package/dist/src/auth/oauth/{vendor-pi-google → google-oauth}/oauth-page.d.ts +0 -0
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
+
import { CredentialResolver, init_credentials } from "../../auth/credentials.js";
|
|
3
4
|
import { getAllProviders, init_providers } from "../../providers/index.js";
|
|
4
5
|
import { formatExamples, register } from "../registry.js";
|
|
5
6
|
import { listAllProfiles, listProfilesForProvider, removeAuthProfile, upsertAuthProfile } from "../../auth/profiles/profiles.js";
|
|
6
7
|
import { colorizeStatus, colors } from "../utils/colors.js";
|
|
7
8
|
import { getOAuthProvider, getSupportedOAuthProviders } from "../utils/oauth-providers.js";
|
|
9
|
+
import { runCliOAuthLogin } from "../utils/oauth-login.js";
|
|
8
10
|
import { Command } from "commander";
|
|
9
11
|
//#region src/cli/commands/auth.ts
|
|
10
12
|
/**
|
|
@@ -12,6 +14,7 @@ import { Command } from "commander";
|
|
|
12
14
|
*
|
|
13
15
|
* Manage authentication credentials (API keys, OAuth tokens, Auth Profiles).
|
|
14
16
|
*/
|
|
17
|
+
init_credentials();
|
|
15
18
|
init_providers();
|
|
16
19
|
init_logger();
|
|
17
20
|
const log = createLogger("AuthCommand");
|
|
@@ -26,8 +29,8 @@ function createAuthCommand(_ctx) {
|
|
|
26
29
|
"xopc auth remove anthropic",
|
|
27
30
|
"xopc auth profiles list"
|
|
28
31
|
]));
|
|
29
|
-
cmd.command("list").description("List all configured authentication credentials").action(() => {
|
|
30
|
-
listAuthProfiles();
|
|
32
|
+
cmd.command("list").description("List all configured authentication credentials").action(async () => {
|
|
33
|
+
await listAuthProfiles();
|
|
31
34
|
});
|
|
32
35
|
cmd.command("set <provider> <key>").description("Set API key for a provider").option("-p, --profile <profileId>", "Profile ID (default: provider:default)").action((provider, key, options) => {
|
|
33
36
|
const profileId = options.profile || `${provider}:default`;
|
|
@@ -60,17 +63,16 @@ function createAuthCommand(_ctx) {
|
|
|
60
63
|
console.log("");
|
|
61
64
|
}
|
|
62
65
|
});
|
|
63
|
-
cmd.command("remove <provider>").description("Remove authentication for a provider").option("-p, --profile <profileId>", "Profile ID to remove").action((provider, options) => {
|
|
66
|
+
cmd.command("remove <provider>").description("Remove authentication for a provider").option("-p, --profile <profileId>", "Profile ID to remove").action(async (provider, options) => {
|
|
64
67
|
if (options.profile) {
|
|
65
68
|
if (removeAuthProfile(options.profile)) log.info(`Profile removed: ${options.profile}`);
|
|
66
69
|
else log.warn(`Profile not found: ${options.profile}`);
|
|
67
70
|
return;
|
|
68
71
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
log.info(`All profiles removed for provider: ${provider}`);
|
|
72
|
+
await new CredentialResolver().deleteProviderCredential(provider);
|
|
73
|
+
log.info(`All credentials removed for provider: ${provider}`);
|
|
72
74
|
});
|
|
73
|
-
cmd.command("login <provider>").description("Login to a provider using OAuth").option("-p, --profile <profileId>", "Profile ID (default: provider:default)").action(async (provider,
|
|
75
|
+
cmd.command("login <provider>").description("Login to a provider using OAuth").option("-p, --profile <profileId>", "Profile ID (default: provider:default)").action(async (provider, _options) => {
|
|
74
76
|
const oauthConfig = getOAuthProvider(provider);
|
|
75
77
|
if (!oauthConfig) {
|
|
76
78
|
log.error(`OAuth not supported for provider: ${provider}`);
|
|
@@ -79,61 +81,29 @@ function createAuthCommand(_ctx) {
|
|
|
79
81
|
process.exit(1);
|
|
80
82
|
}
|
|
81
83
|
log.info(`Starting ${oauthConfig.displayName} OAuth login...`);
|
|
82
|
-
const callbacks = {
|
|
83
|
-
onAuth: (info) => {
|
|
84
|
-
console.log("\n" + oauthConfig.urlPrompt);
|
|
85
|
-
console.log(info.url);
|
|
86
|
-
if (info.instructions) console.log("\n" + info.instructions);
|
|
87
|
-
console.log("\n");
|
|
88
|
-
},
|
|
89
|
-
onDeviceCode: (info) => {
|
|
90
|
-
console.log(`\nOpen ${info.verificationUri} and enter code ${info.userCode}\n`);
|
|
91
|
-
},
|
|
92
|
-
onPrompt: async (prompt) => {
|
|
93
|
-
const { input } = await import("@inquirer/prompts");
|
|
94
|
-
return input({ message: prompt.message });
|
|
95
|
-
},
|
|
96
|
-
onProgress: (message) => {
|
|
97
|
-
log.info(message);
|
|
98
|
-
},
|
|
99
|
-
onSelect: async (prompt) => {
|
|
100
|
-
return prompt.options.find((option) => option.id === "browser")?.id ?? prompt.options[0]?.id;
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
84
|
try {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
profileId,
|
|
108
|
-
credential: {
|
|
109
|
-
type: "oauth",
|
|
110
|
-
provider,
|
|
111
|
-
...creds
|
|
112
|
-
}
|
|
85
|
+
await runCliOAuthLogin({
|
|
86
|
+
provider,
|
|
87
|
+
onProgress: (message) => log.info(message)
|
|
113
88
|
});
|
|
114
|
-
log.info(`✅ OAuth login successful
|
|
89
|
+
log.info(`✅ OAuth login successful for ${provider}`);
|
|
115
90
|
} catch (error) {
|
|
116
91
|
log.error(`OAuth login failed: ${error}`);
|
|
117
92
|
process.exit(1);
|
|
118
93
|
}
|
|
119
94
|
});
|
|
120
|
-
cmd.command("logout <provider>").description("Logout from a provider (remove credentials)").option("-p, --profile <profileId>", "Profile ID to remove").action((provider, options) => {
|
|
95
|
+
cmd.command("logout <provider>").description("Logout from a provider (remove credentials)").option("-p, --profile <profileId>", "Profile ID to remove").action(async (provider, options) => {
|
|
121
96
|
if (options.profile) {
|
|
122
97
|
if (removeAuthProfile(options.profile)) log.info(`Logged out: ${options.profile}`);
|
|
123
98
|
else log.warn(`Profile not found: ${options.profile}`);
|
|
124
99
|
return;
|
|
125
100
|
}
|
|
126
|
-
|
|
127
|
-
if (profiles.length === 0) {
|
|
128
|
-
log.warn(`No profiles found for provider: ${provider}`);
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
for (const profile of profiles) removeAuthProfile(profile.profileId);
|
|
101
|
+
await new CredentialResolver().deleteProviderCredential(provider);
|
|
132
102
|
log.info(`Logged out from provider: ${provider}`);
|
|
133
103
|
});
|
|
134
104
|
const profilesCmd = cmd.command("profiles").description("Manage auth profiles");
|
|
135
|
-
profilesCmd.command("list").description("List all auth profiles").action(() => {
|
|
136
|
-
listAuthProfiles();
|
|
105
|
+
profilesCmd.command("list").description("List all auth profiles").action(async () => {
|
|
106
|
+
await listAuthProfiles();
|
|
137
107
|
});
|
|
138
108
|
profilesCmd.command("add").description("Add a new auth profile").requiredOption("-p, --profile <profileId>", "Profile ID (e.g., openai:work)").requiredOption("-t, --type <type>", "Credential type (api_key, token, oauth)").option("-k, --key <key>", "API key (for api_key type)").option("-e, --email <email>", "Email associated with the credential").action((options) => {
|
|
139
109
|
const { profile, type, key, email } = options;
|
|
@@ -170,9 +140,14 @@ function createAuthCommand(_ctx) {
|
|
|
170
140
|
});
|
|
171
141
|
log.info(`Profile added: ${profile}`);
|
|
172
142
|
});
|
|
173
|
-
cmd.command("clear").description("Clear all authentication credentials").action(() => {
|
|
143
|
+
cmd.command("clear").description("Clear all authentication credentials").action(async () => {
|
|
144
|
+
const resolver = new CredentialResolver();
|
|
174
145
|
const profiles = listAllProfiles();
|
|
175
|
-
|
|
146
|
+
const oauthTokens = await resolver.listOAuthTokens();
|
|
147
|
+
const providers = /* @__PURE__ */ new Set();
|
|
148
|
+
for (const profile of profiles) providers.add(profile.provider);
|
|
149
|
+
for (const token of oauthTokens) providers.add(token.provider);
|
|
150
|
+
for (const provider of providers) await resolver.deleteProviderCredential(provider);
|
|
176
151
|
log.info("All authentication credentials cleared.");
|
|
177
152
|
});
|
|
178
153
|
cmd.command("providers").description("List supported providers and their auth methods").action(() => {
|
|
@@ -184,9 +159,10 @@ function createAuthCommand(_ctx) {
|
|
|
184
159
|
});
|
|
185
160
|
return cmd;
|
|
186
161
|
}
|
|
187
|
-
function listAuthProfiles() {
|
|
162
|
+
async function listAuthProfiles() {
|
|
188
163
|
const profiles = listAllProfiles();
|
|
189
|
-
|
|
164
|
+
const oauthTokens = await new CredentialResolver().listOAuthTokens();
|
|
165
|
+
if (profiles.length === 0 && oauthTokens.length === 0) {
|
|
190
166
|
log.info("No auth profiles configured.");
|
|
191
167
|
log.info("Set an API key: xopc auth set <provider> <key>");
|
|
192
168
|
log.info("Or login with OAuth: xopc auth login <provider>");
|
|
@@ -207,6 +183,18 @@ function listAuthProfiles() {
|
|
|
207
183
|
}
|
|
208
184
|
console.log("");
|
|
209
185
|
}
|
|
186
|
+
for (const token of oauthTokens) {
|
|
187
|
+
const status = colorizeStatus(token.hasAccess);
|
|
188
|
+
console.log(` ${token.provider}:oauth`);
|
|
189
|
+
console.log(` Type: ${colors.yellow("oauth")}`);
|
|
190
|
+
console.log(` Status: ${status} ${token.hasAccess ? "Configured" : "Missing"}`);
|
|
191
|
+
if (token.expiresAt) {
|
|
192
|
+
const expDate = new Date(token.expiresAt);
|
|
193
|
+
const isExpired = Date.now() >= token.expiresAt;
|
|
194
|
+
console.log(` Expires: ${isExpired ? colors.red("") : ""}${expDate.toLocaleString()}`);
|
|
195
|
+
}
|
|
196
|
+
console.log("");
|
|
197
|
+
}
|
|
210
198
|
}
|
|
211
199
|
register({
|
|
212
200
|
id: "auth",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","names":[],"sources":["../../../../src/cli/commands/auth.ts"],"sourcesContent":["/**\n * Auth Command\n * \n * Manage authentication credentials (API keys, OAuth tokens, Auth Profiles).\n */\n\nimport { Command } from 'commander';\nimport { type OAuthLoginCallbacks } from '../../auth/index.js';\nimport {\n\tlistProfilesForProvider,\n\tlistAllProfiles,\n\tupsertAuthProfile,\n\tremoveAuthProfile,\n\ttype AuthProfileCredential,\n} from '../../auth/profiles/index.js';\nimport { getAllProviders } from '../../providers/index.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { register, formatExamples, type CLIContext } from '../registry.js';\nimport { colors, colorizeStatus } from '../utils/colors.js';\nimport { getOAuthProvider, getSupportedOAuthProviders } from '../utils/oauth-providers.js';\n\nconst log = createLogger('AuthCommand');\n\nfunction createAuthCommand(_ctx: CLIContext): Command {\n\tconst cmd = new Command('auth')\n\t\t.description('Manage authentication credentials')\n\t\t.addHelpText(\n\t\t\t'after',\n\t\t\tformatExamples([\n\t\t\t\t'xopc auth list',\n\t\t\t\t'xopc auth set openai sk-xxx',\n\t\t\t\t'xopc auth set anthropic sk-ant-api-xxx',\n\t\t\t\t'xopc auth login anthropic',\n\t\t\t\t'xopc auth login kimi-coding',\n\t\t\t\t'xopc auth logout anthropic',\n\t\t\t\t'xopc auth remove anthropic',\n\t\t\t\t'xopc auth profiles list',\n\t\t\t])\n\t\t);\n\n\t// List command - shows auth profiles\n\tcmd\n\t\t.command('list')\n\t\t.description('List all configured authentication credentials')\n\t\t.action(() => {\n\t\t\tlistAuthProfiles();\n\t\t});\n\n\t// Set command\n\tcmd\n\t\t.command('set <provider> <key>')\n\t\t.description('Set API key for a provider')\n\t\t.option('-p, --profile <profileId>', 'Profile ID (default: provider:default)')\n\t\t.action((provider: string, key: string, options: { profile?: string }) => {\n\t\t\tconst profileId = options.profile || `${provider}:default`;\n\t\t\t\n\t\t\tconst credential: AuthProfileCredential = {\n\t\t\t\ttype: 'api_key',\n\t\t\t\tprovider,\n\t\t\t\tkey,\n\t\t\t};\n\t\t\t\n\t\t\tupsertAuthProfile({ profileId, credential });\n\t\t\tlog.info(`API key set for ${provider} (profile: ${profileId})`);\n\t\t});\n\n\t// Get command\n\tcmd\n\t\t.command('get <provider>')\n\t\t.description('Get API key for a provider (shows masked)')\n\t\t.option('-p, --profile <profileId>', 'Profile ID')\n\t\t.action(async (provider: string, _options: { profile?: string }) => {\n\t\t\tconst profiles = listProfilesForProvider(provider);\n\t\t\t\n\t\t\tif (profiles.length === 0) {\n\t\t\t\tlog.error(`No credentials found for provider: ${provider}`);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tfor (const profile of profiles) {\n\t\t\t\tconst _masked = '****';\n\t\t\t\tconst status = colorizeStatus(profile.hasKey);\n\t\t\t\tconsole.log(`\\nProvider: ${provider}`);\n\t\t\t\tconsole.log(`Profile: ${profile.profileId}`);\n\t\t\t\tconsole.log(`Type: ${profile.type}`);\n\t\t\t\tconsole.log(`Status: ${status} ${profile.hasKey ? 'Configured' : 'Missing'}`);\n\t\t\t\tif (profile.expires) {\n\t\t\t\t\tconst expDate = new Date(profile.expires);\n\t\t\t\t\tconsole.log(`Expires: ${expDate.toLocaleString()}`);\n\t\t\t\t}\n\t\t\t\tconsole.log('');\n\t\t\t}\n\t\t});\n\n\t// Remove command\n\tcmd\n\t\t.command('remove <provider>')\n\t\t.description('Remove authentication for a provider')\n\t\t.option('-p, --profile <profileId>', 'Profile ID to remove')\n\t\t.action((provider: string, options: { profile?: string }) => {\n\t\t\tif (options.profile) {\n\t\t\t\tconst removed = removeAuthProfile(options.profile);\n\t\t\t\tif (removed) {\n\t\t\t\t\tlog.info(`Profile removed: ${options.profile}`);\n\t\t\t\t} else {\n\t\t\t\t\tlog.warn(`Profile not found: ${options.profile}`);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t\n\t\t\t// Remove all profiles for provider\n\t\t\tconst profiles = listProfilesForProvider(provider);\n\t\t\tfor (const profile of profiles) {\n\t\t\t\tremoveAuthProfile(profile.profileId);\n\t\t\t}\n\t\t\tlog.info(`All profiles removed for provider: ${provider}`);\n\t\t});\n\n\t// Login command (OAuth)\n\tcmd\n\t\t.command('login <provider>')\n\t\t.description('Login to a provider using OAuth')\n\t\t.option('-p, --profile <profileId>', 'Profile ID (default: provider:default)')\n\t\t.action(async (provider: string, options: { profile?: string }) => {\n\t\t\tconst oauthConfig = getOAuthProvider(provider);\n\t\t\t\n\t\t\tif (!oauthConfig) {\n\t\t\t\tlog.error(`OAuth not supported for provider: ${provider}`);\n\t\t\t\tlog.info(`Supported OAuth providers: ${getSupportedOAuthProviders().join(', ')}`);\n\t\t\t\tlog.info('Alternatively, set an API key: xopc auth set <provider> <key>');\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tlog.info(`Starting ${oauthConfig.displayName} OAuth login...`);\n\t\t\t\n\t\t\tconst callbacks: OAuthLoginCallbacks = {\n\t\t\t\tonAuth: (info) => {\n\t\t\t\t\tconsole.log('\\n' + oauthConfig.urlPrompt);\n\t\t\t\t\tconsole.log(info.url);\n\t\t\t\t\tif (info.instructions) {\n\t\t\t\t\t\tconsole.log('\\n' + info.instructions);\n\t\t\t\t\t}\n\t\t\t\t\tconsole.log('\\n');\n\t\t\t\t},\n\t\t\t\tonDeviceCode: (info) => {\n\t\t\t\t\tconsole.log(`\\nOpen ${info.verificationUri} and enter code ${info.userCode}\\n`);\n\t\t\t\t},\n\t\t\t\tonPrompt: async (prompt) => {\n\t\t\t\t\tconst { input } = await import('@inquirer/prompts');\n\t\t\t\t\treturn input({ message: prompt.message });\n\t\t\t\t},\n\t\t\t\tonProgress: (message) => {\n\t\t\t\t\tlog.info(message);\n\t\t\t\t},\n\t\t\t\tonSelect: async (prompt) => {\n\t\t\t\t\tconst browserOption = prompt.options.find((option) => option.id === 'browser');\n\t\t\t\t\treturn browserOption?.id ?? prompt.options[0]?.id;\n\t\t\t\t},\n\t\t\t};\n\n\t\t\ttry {\n\t\t\t\tconst creds = await oauthConfig.provider.login(callbacks);\n\t\t\t\tconst profileId = options.profile || oauthConfig.profileId;\n\t\t\t\tupsertAuthProfile({\n\t\t\t\t\tprofileId,\n\t\t\t\t\tcredential: {\n\t\t\t\t\t\ttype: 'oauth',\n\t\t\t\t\t\tprovider,\n\t\t\t\t\t\t...creds,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tlog.info(`✅ OAuth login successful! Profile: ${profileId}`);\n\t\t\t} catch (error) {\n\t\t\t\tlog.error(`OAuth login failed: ${error}`);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t});\n\n\t// Logout command\n\tcmd\n\t\t.command('logout <provider>')\n\t\t.description('Logout from a provider (remove credentials)')\n\t\t.option('-p, --profile <profileId>', 'Profile ID to remove')\n\t\t.action((provider: string, options: { profile?: string }) => {\n\t\t\tif (options.profile) {\n\t\t\t\tconst removed = removeAuthProfile(options.profile);\n\t\t\t\tif (removed) {\n\t\t\t\t\tlog.info(`Logged out: ${options.profile}`);\n\t\t\t\t} else {\n\t\t\t\t\tlog.warn(`Profile not found: ${options.profile}`);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t\n\t\t\t// Remove all profiles for provider\n\t\t\tconst profiles = listProfilesForProvider(provider);\n\t\t\tif (profiles.length === 0) {\n\t\t\t\tlog.warn(`No profiles found for provider: ${provider}`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t\n\t\t\tfor (const profile of profiles) {\n\t\t\t\tremoveAuthProfile(profile.profileId);\n\t\t\t}\n\t\t\tlog.info(`Logged out from provider: ${provider}`);\n\t\t});\n\n\t// Profiles subcommand\n\tconst profilesCmd = cmd\n\t\t.command('profiles')\n\t\t.description('Manage auth profiles');\n\n\tprofilesCmd\n\t\t.command('list')\n\t\t.description('List all auth profiles')\n\t\t.action(() => {\n\t\t\tlistAuthProfiles();\n\t\t});\n\n\tprofilesCmd\n\t\t.command('add')\n\t\t.description('Add a new auth profile')\n\t\t.requiredOption('-p, --profile <profileId>', 'Profile ID (e.g., openai:work)')\n\t\t.requiredOption('-t, --type <type>', 'Credential type (api_key, token, oauth)')\n\t\t.option('-k, --key <key>', 'API key (for api_key type)')\n\t\t.option('-e, --email <email>', 'Email associated with the credential')\n\t\t.action((options) => {\n\t\t\tconst { profile, type, key, email } = options;\n\t\t\t\n\t\t\tlet credential: AuthProfileCredential;\n\t\t\t\n\t\t\tif (type === 'api_key') {\n\t\t\t\tif (!key) {\n\t\t\t\t\tlog.error('API key required for api_key type');\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tcredential = { type: 'api_key', provider: profile.split(':')[0], key, email };\n\t\t\t} else if (type === 'token') {\n\t\t\t\tif (!key) {\n\t\t\t\t\tlog.error('Token required for token type');\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tcredential = { type: 'token', provider: profile.split(':')[0], token: key, email };\n\t\t\t} else {\n\t\t\t\tlog.error('OAuth credentials must be added via \"xopc auth login\"');\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\t\n\t\t\tupsertAuthProfile({ profileId: profile, credential });\n\t\t\tlog.info(`Profile added: ${profile}`);\n\t\t});\n\n\t// Clear command\n\tcmd\n\t\t.command('clear')\n\t\t.description('Clear all authentication credentials')\n\t\t.action(() => {\n\t\t\tconst profiles = listAllProfiles();\n\t\t\tfor (const profile of profiles) {\n\t\t\t\tremoveAuthProfile(profile.profileId);\n\t\t\t}\n\t\t\t\n\t\t\tlog.info('All authentication credentials cleared.');\n\t\t});\n\n\t// Providers command - show supported providers\n\tcmd\n\t\t.command('providers')\n\t\t.description('List supported providers and their auth methods')\n\t\t.action(() => {\n\t\t\tconsole.log('\\nSupported providers:\\n');\n\t\t\t\n\t\t\t// Built-in providers from pi-ai\n\t\t\tconst providers = getAllProviders();\n\t\t\t\n\t\t\tfor (const id of providers) {\n\t\t\t\tconsole.log(` ${id}`);\n\t\t\t}\n\t\t\t\n\t\t\tconsole.log('\\nSet API key: xopc auth set <provider> <key>');\n\t\t\tconsole.log('Environment variables: PROVIDER_API_KEY\\n');\n\t\t});\n\n\treturn cmd;\n}\n\nfunction listAuthProfiles(): void {\n\tconst profiles = listAllProfiles();\n\t\n\tif (profiles.length === 0) {\n\t\tlog.info('No auth profiles configured.');\n\t\tlog.info('Set an API key: xopc auth set <provider> <key>');\n\t\tlog.info('Or login with OAuth: xopc auth login <provider>');\n\t\treturn;\n\t}\n\n\tconsole.log('\\nAuth profiles:\\n');\n\tfor (const profile of profiles) {\n\t\tconst typeColor = profile.type === 'oauth' ? colors.yellow :\n\t\t\tprofile.type === 'token' ? colors.cyan : colors.blue;\n\t\tconst status = colorizeStatus(profile.hasKey);\n\t\t\n\t\tconsole.log(` ${profile.profileId}`);\n\t\tconsole.log(` Type: ${typeColor(profile.type)}`);\n\t\tconsole.log(` Status: ${status} ${profile.hasKey ? 'Configured' : 'Missing'}`);\n\t\tif (profile.email) {\n\t\t\tconsole.log(` Email: ${profile.email}`);\n\t\t}\n\t\tif (profile.expires) {\n\t\t\tconst expDate = new Date(profile.expires);\n\t\t\tconst isExpired = Date.now() >= profile.expires;\n\t\t\tconsole.log(` Expires: ${isExpired ? colors.red('') : ''}${expDate.toLocaleString()}`);\n\t\t}\n\t\tconsole.log('');\n\t}\n}\n\n// Register the command\nregister({\n\tid: 'auth',\n\tname: 'auth',\n\tdescription: 'Manage authentication credentials',\n\tfactory: createAuthCommand,\n\tmetadata: { \n\t\tcategory: 'setup',\n\t\texamples: [\n\t\t\t'xopc auth list',\n\t\t\t'xopc auth providers',\n\t\t\t'xopc auth set openai sk-xxx',\n\t\t\t'xopc auth login anthropic',\n\t\t\t'xopc auth login kimi-coding',\n\t\t\t'xopc auth profiles list',\n\t\t],\n\t},\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"auth.js","names":[],"sources":["../../../../src/cli/commands/auth.ts"],"sourcesContent":["/**\n * Auth Command\n * \n * Manage authentication credentials (API keys, OAuth tokens, Auth Profiles).\n */\n\nimport { Command } from 'commander';\nimport {\n\tlistProfilesForProvider,\n\tlistAllProfiles,\n\tupsertAuthProfile,\n\tremoveAuthProfile,\n\ttype AuthProfileCredential,\n} from '../../auth/profiles/index.js';\nimport { CredentialResolver } from '../../auth/credentials.js';\nimport { getAllProviders } from '../../providers/index.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { register, formatExamples, type CLIContext } from '../registry.js';\nimport { colors, colorizeStatus } from '../utils/colors.js';\nimport { getOAuthProvider, getSupportedOAuthProviders } from '../utils/oauth-providers.js';\nimport { runCliOAuthLogin } from '../utils/oauth-login.js';\n\nconst log = createLogger('AuthCommand');\n\nfunction createAuthCommand(_ctx: CLIContext): Command {\n\tconst cmd = new Command('auth')\n\t\t.description('Manage authentication credentials')\n\t\t.addHelpText(\n\t\t\t'after',\n\t\t\tformatExamples([\n\t\t\t\t'xopc auth list',\n\t\t\t\t'xopc auth set openai sk-xxx',\n\t\t\t\t'xopc auth set anthropic sk-ant-api-xxx',\n\t\t\t\t'xopc auth login anthropic',\n\t\t\t\t'xopc auth login kimi-coding',\n\t\t\t\t'xopc auth logout anthropic',\n\t\t\t\t'xopc auth remove anthropic',\n\t\t\t\t'xopc auth profiles list',\n\t\t\t])\n\t\t);\n\n\t// List command - shows auth profiles\n\tcmd\n\t\t.command('list')\n\t\t.description('List all configured authentication credentials')\n\t\t.action(async () => {\n\t\t\tawait listAuthProfiles();\n\t\t});\n\n\t// Set command\n\tcmd\n\t\t.command('set <provider> <key>')\n\t\t.description('Set API key for a provider')\n\t\t.option('-p, --profile <profileId>', 'Profile ID (default: provider:default)')\n\t\t.action((provider: string, key: string, options: { profile?: string }) => {\n\t\t\tconst profileId = options.profile || `${provider}:default`;\n\t\t\t\n\t\t\tconst credential: AuthProfileCredential = {\n\t\t\t\ttype: 'api_key',\n\t\t\t\tprovider,\n\t\t\t\tkey,\n\t\t\t};\n\t\t\t\n\t\t\tupsertAuthProfile({ profileId, credential });\n\t\t\tlog.info(`API key set for ${provider} (profile: ${profileId})`);\n\t\t});\n\n\t// Get command\n\tcmd\n\t\t.command('get <provider>')\n\t\t.description('Get API key for a provider (shows masked)')\n\t\t.option('-p, --profile <profileId>', 'Profile ID')\n\t\t.action(async (provider: string, _options: { profile?: string }) => {\n\t\t\tconst profiles = listProfilesForProvider(provider);\n\t\t\t\n\t\t\tif (profiles.length === 0) {\n\t\t\t\tlog.error(`No credentials found for provider: ${provider}`);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tfor (const profile of profiles) {\n\t\t\t\tconst _masked = '****';\n\t\t\t\tconst status = colorizeStatus(profile.hasKey);\n\t\t\t\tconsole.log(`\\nProvider: ${provider}`);\n\t\t\t\tconsole.log(`Profile: ${profile.profileId}`);\n\t\t\t\tconsole.log(`Type: ${profile.type}`);\n\t\t\t\tconsole.log(`Status: ${status} ${profile.hasKey ? 'Configured' : 'Missing'}`);\n\t\t\t\tif (profile.expires) {\n\t\t\t\t\tconst expDate = new Date(profile.expires);\n\t\t\t\t\tconsole.log(`Expires: ${expDate.toLocaleString()}`);\n\t\t\t\t}\n\t\t\t\tconsole.log('');\n\t\t\t}\n\t\t});\n\n\t// Remove command\n\tcmd\n\t\t.command('remove <provider>')\n\t\t.description('Remove authentication for a provider')\n\t\t.option('-p, --profile <profileId>', 'Profile ID to remove')\n\t\t.action(async (provider: string, options: { profile?: string }) => {\n\t\t\tif (options.profile) {\n\t\t\t\tconst removed = removeAuthProfile(options.profile);\n\t\t\t\tif (removed) {\n\t\t\t\t\tlog.info(`Profile removed: ${options.profile}`);\n\t\t\t\t} else {\n\t\t\t\t\tlog.warn(`Profile not found: ${options.profile}`);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t\n\t\t\tawait new CredentialResolver().deleteProviderCredential(provider);\n\t\t\tlog.info(`All credentials removed for provider: ${provider}`);\n\t\t});\n\n\t// Login command (OAuth)\n\tcmd\n\t\t.command('login <provider>')\n\t\t.description('Login to a provider using OAuth')\n\t\t.option('-p, --profile <profileId>', 'Profile ID (default: provider:default)')\n\t\t.action(async (provider: string, _options: { profile?: string }) => {\n\t\t\tconst oauthConfig = getOAuthProvider(provider);\n\t\t\t\n\t\t\tif (!oauthConfig) {\n\t\t\t\tlog.error(`OAuth not supported for provider: ${provider}`);\n\t\t\t\tlog.info(`Supported OAuth providers: ${getSupportedOAuthProviders().join(', ')}`);\n\t\t\t\tlog.info('Alternatively, set an API key: xopc auth set <provider> <key>');\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tlog.info(`Starting ${oauthConfig.displayName} OAuth login...`);\n\n\t\t\ttry {\n\t\t\t\tawait runCliOAuthLogin({ provider, onProgress: (message) => log.info(message) });\n\t\t\t\tlog.info(`✅ OAuth login successful for ${provider}`);\n\t\t\t} catch (error) {\n\t\t\t\tlog.error(`OAuth login failed: ${error}`);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t});\n\n\t// Logout command\n\tcmd\n\t\t.command('logout <provider>')\n\t\t.description('Logout from a provider (remove credentials)')\n\t\t.option('-p, --profile <profileId>', 'Profile ID to remove')\n\t\t.action(async (provider: string, options: { profile?: string }) => {\n\t\t\tif (options.profile) {\n\t\t\t\tconst removed = removeAuthProfile(options.profile);\n\t\t\t\tif (removed) {\n\t\t\t\t\tlog.info(`Logged out: ${options.profile}`);\n\t\t\t\t} else {\n\t\t\t\t\tlog.warn(`Profile not found: ${options.profile}`);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t\n\t\t\tawait new CredentialResolver().deleteProviderCredential(provider);\n\t\t\tlog.info(`Logged out from provider: ${provider}`);\n\t\t});\n\n\t// Profiles subcommand\n\tconst profilesCmd = cmd\n\t\t.command('profiles')\n\t\t.description('Manage auth profiles');\n\n\tprofilesCmd\n\t\t.command('list')\n\t\t.description('List all auth profiles')\n\t\t.action(async () => {\n\t\t\tawait listAuthProfiles();\n\t\t});\n\n\tprofilesCmd\n\t\t.command('add')\n\t\t.description('Add a new auth profile')\n\t\t.requiredOption('-p, --profile <profileId>', 'Profile ID (e.g., openai:work)')\n\t\t.requiredOption('-t, --type <type>', 'Credential type (api_key, token, oauth)')\n\t\t.option('-k, --key <key>', 'API key (for api_key type)')\n\t\t.option('-e, --email <email>', 'Email associated with the credential')\n\t\t.action((options) => {\n\t\t\tconst { profile, type, key, email } = options;\n\t\t\t\n\t\t\tlet credential: AuthProfileCredential;\n\t\t\t\n\t\t\tif (type === 'api_key') {\n\t\t\t\tif (!key) {\n\t\t\t\t\tlog.error('API key required for api_key type');\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tcredential = { type: 'api_key', provider: profile.split(':')[0], key, email };\n\t\t\t} else if (type === 'token') {\n\t\t\t\tif (!key) {\n\t\t\t\t\tlog.error('Token required for token type');\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\t\t\t\tcredential = { type: 'token', provider: profile.split(':')[0], token: key, email };\n\t\t\t} else {\n\t\t\t\tlog.error('OAuth credentials must be added via \"xopc auth login\"');\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\t\n\t\t\tupsertAuthProfile({ profileId: profile, credential });\n\t\t\tlog.info(`Profile added: ${profile}`);\n\t\t});\n\n\t// Clear command\n\tcmd\n\t\t.command('clear')\n\t\t.description('Clear all authentication credentials')\n\t\t.action(async () => {\n\t\t\tconst resolver = new CredentialResolver();\n\t\t\tconst profiles = listAllProfiles();\n\t\t\tconst oauthTokens = await resolver.listOAuthTokens();\n\t\t\tconst providers = new Set<string>();\n\t\t\tfor (const profile of profiles) providers.add(profile.provider);\n\t\t\tfor (const token of oauthTokens) providers.add(token.provider);\n\t\t\tfor (const provider of providers) {\n\t\t\t\tawait resolver.deleteProviderCredential(provider);\n\t\t\t}\n\t\t\t\n\t\t\tlog.info('All authentication credentials cleared.');\n\t\t});\n\n\t// Providers command - show supported providers\n\tcmd\n\t\t.command('providers')\n\t\t.description('List supported providers and their auth methods')\n\t\t.action(() => {\n\t\t\tconsole.log('\\nSupported providers:\\n');\n\t\t\t\n\t\t\t// Built-in providers from pi-ai\n\t\t\tconst providers = getAllProviders();\n\t\t\t\n\t\t\tfor (const id of providers) {\n\t\t\t\tconsole.log(` ${id}`);\n\t\t\t}\n\t\t\t\n\t\t\tconsole.log('\\nSet API key: xopc auth set <provider> <key>');\n\t\t\tconsole.log('Environment variables: PROVIDER_API_KEY\\n');\n\t\t});\n\n\treturn cmd;\n}\n\nasync function listAuthProfiles(): Promise<void> {\n\tconst profiles = listAllProfiles();\n\tconst oauthTokens = await new CredentialResolver().listOAuthTokens();\n\t\n\tif (profiles.length === 0 && oauthTokens.length === 0) {\n\t\tlog.info('No auth profiles configured.');\n\t\tlog.info('Set an API key: xopc auth set <provider> <key>');\n\t\tlog.info('Or login with OAuth: xopc auth login <provider>');\n\t\treturn;\n\t}\n\n\tconsole.log('\\nAuth profiles:\\n');\n\tfor (const profile of profiles) {\n\t\tconst typeColor = profile.type === 'oauth' ? colors.yellow :\n\t\t\tprofile.type === 'token' ? colors.cyan : colors.blue;\n\t\tconst status = colorizeStatus(profile.hasKey);\n\t\t\n\t\tconsole.log(` ${profile.profileId}`);\n\t\tconsole.log(` Type: ${typeColor(profile.type)}`);\n\t\tconsole.log(` Status: ${status} ${profile.hasKey ? 'Configured' : 'Missing'}`);\n\t\tif (profile.email) {\n\t\t\tconsole.log(` Email: ${profile.email}`);\n\t\t}\n\t\tif (profile.expires) {\n\t\t\tconst expDate = new Date(profile.expires);\n\t\t\tconst isExpired = Date.now() >= profile.expires;\n\t\t\tconsole.log(` Expires: ${isExpired ? colors.red('') : ''}${expDate.toLocaleString()}`);\n\t\t}\n\t\tconsole.log('');\n\t}\n\n\tfor (const token of oauthTokens) {\n\t\tconst status = colorizeStatus(token.hasAccess);\n\t\tconsole.log(` ${token.provider}:oauth`);\n\t\tconsole.log(` Type: ${colors.yellow('oauth')}`);\n\t\tconsole.log(` Status: ${status} ${token.hasAccess ? 'Configured' : 'Missing'}`);\n\t\tif (token.expiresAt) {\n\t\t\tconst expDate = new Date(token.expiresAt);\n\t\t\tconst isExpired = Date.now() >= token.expiresAt;\n\t\t\tconsole.log(` Expires: ${isExpired ? colors.red('') : ''}${expDate.toLocaleString()}`);\n\t\t}\n\t\tconsole.log('');\n\t}\n}\n\n// Register the command\nregister({\n\tid: 'auth',\n\tname: 'auth',\n\tdescription: 'Manage authentication credentials',\n\tfactory: createAuthCommand,\n\tmetadata: { \n\t\tcategory: 'setup',\n\t\texamples: [\n\t\t\t'xopc auth list',\n\t\t\t'xopc auth providers',\n\t\t\t'xopc auth set openai sk-xxx',\n\t\t\t'xopc auth login anthropic',\n\t\t\t'xopc auth login kimi-coding',\n\t\t\t'xopc auth profiles list',\n\t\t],\n\t},\n});\n"],"mappings":"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"}
|
|
@@ -1,92 +1,204 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { CredentialResolver, init_credentials } from "../../auth/credentials.js";
|
|
2
|
+
import { loadConfig, saveConfig } from "../../config/loader.js";
|
|
3
|
+
import { getAllModels, getAvailableModels, getConfiguredProviders, getProviderAuthState, getProviderDisplayName, init_providers, isProviderConfigured, providerSupportsApiKey, providerSupportsOAuth, resolveModel } from "../../providers/index.js";
|
|
3
4
|
import { formatExamples, register } from "../registry.js";
|
|
4
5
|
import { getContextWithOpts } from "../context.js";
|
|
5
6
|
import "../../config/index.js";
|
|
7
|
+
import { colors } from "../utils/colors.js";
|
|
8
|
+
import { runCliOAuthLogin } from "../utils/oauth-login.js";
|
|
9
|
+
import { input } from "@inquirer/prompts";
|
|
6
10
|
import { Command } from "commander";
|
|
7
11
|
//#region src/cli/commands/models.ts
|
|
12
|
+
init_credentials();
|
|
8
13
|
init_providers();
|
|
14
|
+
const IMAGE_GENERATION_IDS = new Set([
|
|
15
|
+
"gpt-image-1",
|
|
16
|
+
"dall-e-3",
|
|
17
|
+
"dall-e-2",
|
|
18
|
+
"wan2.6-t2i",
|
|
19
|
+
"wan2.7-image-pro",
|
|
20
|
+
"wan2.7-image",
|
|
21
|
+
"wan2.1-t2i-turbo",
|
|
22
|
+
"wan2.1-t2i-plus",
|
|
23
|
+
"image-01",
|
|
24
|
+
"image-01-live"
|
|
25
|
+
]);
|
|
26
|
+
const VISION_IDS = new Set([
|
|
27
|
+
"gpt-4o",
|
|
28
|
+
"gpt-4o-mini",
|
|
29
|
+
"gpt-4-turbo",
|
|
30
|
+
"claude-sonnet-4-5",
|
|
31
|
+
"claude-haiku-3-5",
|
|
32
|
+
"gemini-2.0-flash",
|
|
33
|
+
"gemini-1.5-pro",
|
|
34
|
+
"qwen-vl-max",
|
|
35
|
+
"qwen2.5-vl-72b-instruct"
|
|
36
|
+
]);
|
|
37
|
+
function currentModelRef(config) {
|
|
38
|
+
return config.agents?.defaults?.model?.primary;
|
|
39
|
+
}
|
|
40
|
+
function setDefaultModel(config, modelRef) {
|
|
41
|
+
config.agents = config.agents ?? {};
|
|
42
|
+
config.agents.defaults = config.agents.defaults ?? {};
|
|
43
|
+
config.agents.defaults.model = {
|
|
44
|
+
primary: modelRef,
|
|
45
|
+
fallbacks: []
|
|
46
|
+
};
|
|
47
|
+
return config;
|
|
48
|
+
}
|
|
49
|
+
function modelRef(provider, id) {
|
|
50
|
+
return `${provider}/${id}`;
|
|
51
|
+
}
|
|
9
52
|
async function runModelsList(options) {
|
|
10
53
|
const config = loadConfig(getContextWithOpts().configPath);
|
|
11
54
|
const configuredProviders = await getConfiguredProviders();
|
|
55
|
+
const providerFilter = options.provider?.trim();
|
|
56
|
+
const models = (options.all ? getAllModels() : await getAvailableModels()).filter((m) => providerFilter ? m.provider === providerFilter : true);
|
|
12
57
|
if (options.json) {
|
|
13
|
-
const models = options.all ? getAllModels() : await getAvailableModels();
|
|
14
58
|
console.log(JSON.stringify({
|
|
59
|
+
defaultModel: currentModelRef(config) ?? null,
|
|
15
60
|
providers: configuredProviders,
|
|
16
61
|
models: models.map((m) => ({
|
|
17
|
-
id:
|
|
62
|
+
id: modelRef(m.provider, m.id),
|
|
18
63
|
name: m.name,
|
|
19
|
-
provider: m.provider
|
|
64
|
+
provider: m.provider,
|
|
65
|
+
authConfigured: configuredProviders.includes(m.provider)
|
|
20
66
|
}))
|
|
21
67
|
}, null, 2));
|
|
22
68
|
return;
|
|
23
69
|
}
|
|
24
|
-
console.log("\n🤖
|
|
70
|
+
console.log("\n🤖 Models\n");
|
|
25
71
|
console.log("═".repeat(60));
|
|
26
|
-
|
|
27
|
-
console.log("\n📦 Configured Providers\n");
|
|
28
|
-
for (const provider of configuredProviders) console.log(` ✓ ${provider}`);
|
|
29
|
-
console.log("");
|
|
30
|
-
}
|
|
31
|
-
const models = options.all ? getAllModels() : await getAvailableModels();
|
|
32
|
-
console.log("\n📚 Models\n");
|
|
72
|
+
console.log(`\n📌 Current default model: ${currentModelRef(config) ?? "Not set"}\n`);
|
|
33
73
|
const byProvider = /* @__PURE__ */ new Map();
|
|
34
74
|
for (const model of models) {
|
|
35
75
|
const list = byProvider.get(model.provider) ?? [];
|
|
36
76
|
list.push(model);
|
|
37
77
|
byProvider.set(model.provider, list);
|
|
38
78
|
}
|
|
39
|
-
const IMAGE_GENERATION_IDS = new Set([
|
|
40
|
-
"gpt-image-1",
|
|
41
|
-
"dall-e-3",
|
|
42
|
-
"dall-e-2",
|
|
43
|
-
"wan2.6-t2i",
|
|
44
|
-
"wan2.7-image-pro",
|
|
45
|
-
"wan2.7-image",
|
|
46
|
-
"wan2.1-t2i-turbo",
|
|
47
|
-
"wan2.1-t2i-plus",
|
|
48
|
-
"image-01",
|
|
49
|
-
"image-01-live"
|
|
50
|
-
]);
|
|
51
|
-
const VISION_IDS = new Set([
|
|
52
|
-
"gpt-4o",
|
|
53
|
-
"gpt-4o-mini",
|
|
54
|
-
"gpt-4-turbo",
|
|
55
|
-
"claude-sonnet-4-5",
|
|
56
|
-
"claude-haiku-3-5",
|
|
57
|
-
"gemini-2.0-flash",
|
|
58
|
-
"gemini-1.5-pro",
|
|
59
|
-
"qwen-vl-max",
|
|
60
|
-
"qwen2.5-vl-72b-instruct"
|
|
61
|
-
]);
|
|
62
79
|
for (const [provider, providerModels] of byProvider) {
|
|
63
|
-
|
|
80
|
+
const available = await isProviderConfigured(provider);
|
|
81
|
+
console.log(` [${provider}] ${available ? colors.green("configured") : colors.gray("not configured")}`);
|
|
64
82
|
for (const model of providerModels) {
|
|
65
|
-
const status = await isProviderConfigured(provider) ? "✓" : "○";
|
|
66
83
|
const badges = [];
|
|
67
84
|
if (IMAGE_GENERATION_IDS.has(model.id)) badges.push("gen");
|
|
68
85
|
if (model.input?.includes("image") || VISION_IDS.has(model.id)) badges.push("vision");
|
|
69
86
|
const badgeStr = badges.length > 0 ? ` [${badges.join(", ")}]` : "";
|
|
70
|
-
console.log(` ${
|
|
87
|
+
console.log(` ${available ? "✓" : "○"} ${modelRef(model.provider, model.id)}${badgeStr}`);
|
|
71
88
|
}
|
|
72
89
|
}
|
|
73
|
-
console.log("");
|
|
74
|
-
console.log("
|
|
75
|
-
console.log(
|
|
76
|
-
console.log("
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
90
|
+
console.log("\nUsage:");
|
|
91
|
+
console.log(" xopc models set openai/gpt-5.5");
|
|
92
|
+
console.log(" xopc models auth login --provider anthropic");
|
|
93
|
+
console.log(" xopc models auth paste-api-key --provider deepseek");
|
|
94
|
+
}
|
|
95
|
+
async function runModelsStatus(options) {
|
|
96
|
+
const config = loadConfig(getContextWithOpts().configPath);
|
|
97
|
+
const providers = Array.from(new Set(getAllModels().map((m) => m.provider))).sort();
|
|
98
|
+
const auth = [];
|
|
99
|
+
for (const provider of providers) {
|
|
100
|
+
const state = await getProviderAuthState(provider);
|
|
101
|
+
if (state.authMode !== "none") auth.push({
|
|
102
|
+
provider,
|
|
103
|
+
...state
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
if (options.json) {
|
|
107
|
+
console.log(JSON.stringify({
|
|
108
|
+
defaultModel: currentModelRef(config) ?? null,
|
|
109
|
+
auth
|
|
110
|
+
}, null, 2));
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
console.log("\n🤖 Model status\n");
|
|
114
|
+
console.log(`Default: ${currentModelRef(config) ?? "Not set"}`);
|
|
115
|
+
console.log("\nAuth:");
|
|
116
|
+
if (auth.length === 0) {
|
|
117
|
+
console.log(" No provider credentials configured.");
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
for (const entry of auth) {
|
|
121
|
+
const status = entry.authStatus === "connected" ? colors.green(entry.authStatus) : colors.yellow(entry.authStatus);
|
|
122
|
+
console.log(` ${entry.provider}: ${status} (${entry.authMode})`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
async function runModelsSet(model) {
|
|
126
|
+
const ctx = getContextWithOpts();
|
|
127
|
+
const config = loadConfig(ctx.configPath);
|
|
128
|
+
const resolved = resolveModel(model);
|
|
129
|
+
const ref = modelRef(resolved.provider, resolved.id);
|
|
130
|
+
setDefaultModel(config, ref);
|
|
131
|
+
await saveConfig(config, ctx.configPath);
|
|
132
|
+
console.log(`✅ Default model set: ${ref}`);
|
|
133
|
+
}
|
|
134
|
+
async function runAuthList(options) {
|
|
135
|
+
const resolver = new CredentialResolver();
|
|
136
|
+
const profiles = (await resolver.listProfiles()).filter((profile) => options.provider ? profile.provider === options.provider : true);
|
|
137
|
+
const oauthTokens = (await resolver.listOAuthTokens()).filter((token) => options.provider ? token.provider === options.provider : true);
|
|
138
|
+
if (options.json) {
|
|
139
|
+
console.log(JSON.stringify({
|
|
140
|
+
profiles,
|
|
141
|
+
oauth: oauthTokens
|
|
142
|
+
}, null, 2));
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
console.log("\n🔐 Model auth\n");
|
|
146
|
+
if (profiles.length === 0 && oauthTokens.length === 0) {
|
|
147
|
+
console.log(" No model credentials configured.");
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
for (const profile of profiles) console.log(` ${profile.id} ${colors.blue("api-key")} ${profile.provider} ${profile.source}`);
|
|
151
|
+
for (const token of oauthTokens) {
|
|
152
|
+
const expires = token.expiresAt ? ` expires ${new Date(token.expiresAt).toLocaleString()}` : "";
|
|
153
|
+
console.log(` ${token.provider}:oauth ${colors.yellow("oauth")} ${token.hasAccess ? "configured" : "missing"}${expires}`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
async function runAuthPasteApiKey(provider) {
|
|
157
|
+
if (!providerSupportsApiKey(provider)) throw new Error(`Provider ${provider} does not support API key auth`);
|
|
158
|
+
const key = await input({
|
|
159
|
+
message: `API key for ${provider}:`,
|
|
160
|
+
validate: (value) => value.trim().length > 0 || "Required"
|
|
161
|
+
});
|
|
162
|
+
await new CredentialResolver().saveApiKey(provider, key.trim(), { profileName: "default" });
|
|
163
|
+
console.log(`✅ API key saved for ${provider}`);
|
|
164
|
+
}
|
|
165
|
+
function resolveAuthMethod(provider, rawMethod) {
|
|
166
|
+
if (rawMethod && rawMethod !== "oauth" && rawMethod !== "api-key") throw new Error(`Unsupported auth method: ${rawMethod}`);
|
|
167
|
+
if (rawMethod === "oauth" || rawMethod === "api-key") return rawMethod;
|
|
168
|
+
return providerSupportsOAuth(provider) ? "oauth" : "api-key";
|
|
169
|
+
}
|
|
170
|
+
async function runAuthLogin(provider, options) {
|
|
171
|
+
if (resolveAuthMethod(provider, options.method) === "api-key") await runAuthPasteApiKey(provider);
|
|
172
|
+
else {
|
|
173
|
+
if (!providerSupportsOAuth(provider)) throw new Error(`Provider ${provider} does not support OAuth`);
|
|
174
|
+
console.log(`\n🔐 Starting ${getProviderDisplayName(provider)} OAuth login...`);
|
|
175
|
+
await runCliOAuthLogin({
|
|
176
|
+
provider,
|
|
177
|
+
onProgress: (message) => console.log(" →", message)
|
|
178
|
+
});
|
|
179
|
+
console.log(`✅ OAuth login successful for ${provider}`);
|
|
180
|
+
}
|
|
181
|
+
if (options.setDefault) {
|
|
182
|
+
const first = getAllModels().find((model) => model.provider === provider);
|
|
183
|
+
if (!first) throw new Error(`No models found for provider ${provider}`);
|
|
184
|
+
await runModelsSet(modelRef(first.provider, first.id));
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
async function runAuthLogout(provider) {
|
|
188
|
+
await new CredentialResolver().deleteProviderCredential(provider);
|
|
189
|
+
console.log(`✅ Credentials removed for ${provider}`);
|
|
80
190
|
}
|
|
81
191
|
function attachModelsListOptions(command) {
|
|
82
|
-
return command.option("--json", "Output as JSON", false).option("--all, -a", "Show all built-in models", false);
|
|
192
|
+
return command.option("--json", "Output as JSON", false).option("--all, -a", "Show all built-in models", false).option("--provider <id>", "Filter by provider id");
|
|
83
193
|
}
|
|
84
194
|
function createModelsCommand(_ctx) {
|
|
85
|
-
const cmd = new Command("models").description("List and manage
|
|
86
|
-
"xopc models list
|
|
87
|
-
"xopc models
|
|
88
|
-
"xopc models
|
|
89
|
-
"xopc models
|
|
195
|
+
const cmd = new Command("models").description("List and manage models and model auth").addHelpText("after", formatExamples([
|
|
196
|
+
"xopc models list",
|
|
197
|
+
"xopc models status",
|
|
198
|
+
"xopc models set openai/gpt-5.5",
|
|
199
|
+
"xopc models auth list",
|
|
200
|
+
"xopc models auth login --provider anthropic",
|
|
201
|
+
"xopc models auth paste-api-key --provider deepseek"
|
|
90
202
|
]));
|
|
91
203
|
attachModelsListOptions(cmd).action(async (options) => {
|
|
92
204
|
await runModelsList(options);
|
|
@@ -94,16 +206,39 @@ function createModelsCommand(_ctx) {
|
|
|
94
206
|
attachModelsListOptions(cmd.command("list").description("List available models")).action(async (options) => {
|
|
95
207
|
await runModelsList(options);
|
|
96
208
|
});
|
|
209
|
+
cmd.command("status").description("Show default model and provider auth status").option("--json", "Output as JSON", false).action(async (options) => {
|
|
210
|
+
await runModelsStatus(options);
|
|
211
|
+
});
|
|
212
|
+
cmd.command("set <model>").description("Set the default model").action(async (model) => {
|
|
213
|
+
await runModelsSet(model);
|
|
214
|
+
});
|
|
215
|
+
const auth = cmd.command("auth").description("Manage model provider auth");
|
|
216
|
+
auth.command("list").description("List model auth credentials").option("--provider <id>", "Filter by provider id").option("--json", "Output as JSON", false).action(async (options) => {
|
|
217
|
+
await runAuthList(options);
|
|
218
|
+
});
|
|
219
|
+
auth.command("login").description("Run provider auth flow").requiredOption("--provider <id>", "Provider id").option("--method <method>", "Auth method: oauth or api-key").option("--set-default", "Set the provider first model as default after login", false).action(async (options) => {
|
|
220
|
+
await runAuthLogin(options.provider, options);
|
|
221
|
+
});
|
|
222
|
+
auth.command("paste-api-key").description("Paste and save an API key").requiredOption("--provider <id>", "Provider id").action(async (options) => {
|
|
223
|
+
await runAuthPasteApiKey(options.provider);
|
|
224
|
+
});
|
|
225
|
+
auth.command("logout").description("Remove provider credentials").requiredOption("--provider <id>", "Provider id").action(async (options) => {
|
|
226
|
+
await runAuthLogout(options.provider);
|
|
227
|
+
});
|
|
97
228
|
return cmd;
|
|
98
229
|
}
|
|
99
230
|
register({
|
|
100
231
|
id: "models",
|
|
101
232
|
name: "models",
|
|
102
|
-
description: "List and manage
|
|
233
|
+
description: "List and manage models and model auth",
|
|
103
234
|
factory: createModelsCommand,
|
|
104
235
|
metadata: {
|
|
105
236
|
category: "utility",
|
|
106
|
-
examples: [
|
|
237
|
+
examples: [
|
|
238
|
+
"xopc models list",
|
|
239
|
+
"xopc models status",
|
|
240
|
+
"xopc models auth list"
|
|
241
|
+
]
|
|
107
242
|
}
|
|
108
243
|
});
|
|
109
244
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"models.js","names":[],"sources":["../../../../src/cli/commands/models.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { register, formatExamples, type CLIContext } from '../registry.js';\nimport { getContextWithOpts } from '../context.js';\nimport {\n getAllModels,\n getAvailableModels,\n getConfiguredProviders,\n isProviderConfigured,\n} from '../../providers/index.js';\nimport { loadConfig } from '../../config/index.js';\n\ntype ModelsListOptions = {\n json?: boolean;\n all?: boolean;\n};\n\nasync function runModelsList(options: ModelsListOptions): Promise<void> {\n const ctx = getContextWithOpts();\n const config = loadConfig(ctx.configPath);\n const configuredProviders = await getConfiguredProviders();\n\n if (options.json) {\n const models = options.all ? getAllModels() : await getAvailableModels();\n console.log(\n JSON.stringify(\n {\n providers: configuredProviders,\n models: models.map((m) => ({\n id: `${m.provider}/${m.id}`,\n name: m.name,\n provider: m.provider,\n })),\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n console.log('\\n🤖 Available Models\\n');\n console.log('═'.repeat(60));\n\n if (configuredProviders.length > 0) {\n console.log('\\n📦 Configured Providers\\n');\n for (const provider of configuredProviders) {\n console.log(` ✓ ${provider}`);\n }\n console.log('');\n }\n\n const models = options.all ? getAllModels() : await getAvailableModels();\n\n console.log('\\n📚 Models\\n');\n\n const byProvider = new Map<string, ReturnType<typeof getAllModels>[number][]>();\n for (const model of models) {\n const list = byProvider.get(model.provider) ?? [];\n list.push(model);\n byProvider.set(model.provider, list);\n }\n\n const IMAGE_GENERATION_IDS = new Set([\n 'gpt-image-1',\n 'dall-e-3',\n 'dall-e-2',\n 'wan2.6-t2i',\n 'wan2.7-image-pro',\n 'wan2.7-image',\n 'wan2.1-t2i-turbo',\n 'wan2.1-t2i-plus',\n 'image-01',\n 'image-01-live',\n ]);\n const VISION_IDS = new Set([\n 'gpt-4o',\n 'gpt-4o-mini',\n 'gpt-4-turbo',\n 'claude-sonnet-4-5',\n 'claude-haiku-3-5',\n 'gemini-2.0-flash',\n 'gemini-1.5-pro',\n 'qwen-vl-max',\n 'qwen2.5-vl-72b-instruct',\n ]);\n\n for (const [provider, providerModels] of byProvider) {\n console.log(` [${provider}]`);\n for (const model of providerModels) {\n const available = await isProviderConfigured(provider);\n const status = available ? '✓' : '○';\n const badges: string[] = [];\n if (IMAGE_GENERATION_IDS.has(model.id)) {\n badges.push('gen');\n }\n if (model.input?.includes('image') || VISION_IDS.has(model.id)) {\n badges.push('vision');\n }\n const badgeStr = badges.length > 0 ? ` [${badges.join(', ')}]` : '';\n console.log(` ${status} ${model.name}${badgeStr}`);\n }\n }\n console.log('');\n\n console.log('═'.repeat(60));\n console.log(`\\n📌 Current default model: ${config.agents?.defaults?.model || 'Not set'}`);\n\n console.log('\\n📝 Usage:');\n console.log(' export OPENAI_API_KEY=\"sk-...\" # Set API key via env');\n console.log(' xopc agent -m \"Hello\" # Use default model');\n console.log(' xopc agent -m \"Hello\" --model openai/gpt-4o # Specify model');\n}\n\nfunction attachModelsListOptions(command: Command): Command {\n return command\n .option('--json', 'Output as JSON', false)\n .option('--all, -a', 'Show all built-in models', false);\n}\n\nfunction createModelsCommand(_ctx: CLIContext): Command {\n const cmd = new Command('models')\n .description('List and manage available models')\n .addHelpText(\n 'after',\n formatExamples([\n 'xopc models list # List all available models',\n 'xopc models list --all # Show all built-in models',\n 'xopc models list --json # Output as JSON',\n 'xopc models --all # Same as models list --all',\n ]),\n );\n\n attachModelsListOptions(cmd).action(async (options) => {\n await runModelsList(options);\n });\n\n attachModelsListOptions(\n cmd.command('list').description('List available models'),\n ).action(async (options) => {\n await runModelsList(options);\n });\n\n return cmd;\n}\n\nregister({\n id: 'models',\n name: 'models',\n description: 'List and manage available models',\n factory: createModelsCommand,\n metadata: {\n category: 'utility',\n examples: [\n 'xopc models list',\n 'xopc models list --all',\n ],\n },\n});\n\nexport { createModelsCommand };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"models.js","names":[],"sources":["../../../../src/cli/commands/models.ts"],"sourcesContent":["import { input } from '@inquirer/prompts';\nimport { Command } from 'commander';\n\nimport { CredentialResolver } from '../../auth/credentials.js';\nimport { loadConfig, saveConfig } from '../../config/index.js';\nimport type { Config } from '../../config/schema.js';\nimport {\n getAllModels,\n getAvailableModels,\n getConfiguredProviders,\n getProviderAuthState,\n getProviderDisplayName,\n isProviderConfigured,\n providerSupportsApiKey,\n providerSupportsOAuth,\n resolveModel,\n} from '../../providers/index.js';\n\nimport { getContextWithOpts } from '../context.js';\nimport { register, formatExamples, type CLIContext } from '../registry.js';\nimport { colors } from '../utils/colors.js';\nimport { runCliOAuthLogin } from '../utils/oauth-login.js';\n\nconst IMAGE_GENERATION_IDS = new Set([\n 'gpt-image-1',\n 'dall-e-3',\n 'dall-e-2',\n 'wan2.6-t2i',\n 'wan2.7-image-pro',\n 'wan2.7-image',\n 'wan2.1-t2i-turbo',\n 'wan2.1-t2i-plus',\n 'image-01',\n 'image-01-live',\n]);\n\nconst VISION_IDS = new Set([\n 'gpt-4o',\n 'gpt-4o-mini',\n 'gpt-4-turbo',\n 'claude-sonnet-4-5',\n 'claude-haiku-3-5',\n 'gemini-2.0-flash',\n 'gemini-1.5-pro',\n 'qwen-vl-max',\n 'qwen2.5-vl-72b-instruct',\n]);\n\ntype ModelsListOptions = {\n json?: boolean;\n all?: boolean;\n provider?: string;\n};\n\ntype ModelsAuthListOptions = {\n provider?: string;\n json?: boolean;\n};\n\ntype ModelsAuthLoginOptions = {\n method?: 'oauth' | 'api-key';\n setDefault?: boolean;\n};\n\nfunction currentModelRef(config: Config): string | undefined {\n return config.agents?.defaults?.model?.primary;\n}\n\nfunction setDefaultModel(config: Config, modelRef: string): Config {\n config.agents = config.agents ?? {};\n config.agents.defaults = config.agents.defaults ?? {} as NonNullable<Config['agents']>['defaults'];\n config.agents.defaults.model = { primary: modelRef, fallbacks: [] };\n return config;\n}\n\nfunction modelRef(provider: string, id: string): string {\n return `${provider}/${id}`;\n}\n\nasync function runModelsList(options: ModelsListOptions): Promise<void> {\n const ctx = getContextWithOpts();\n const config = loadConfig(ctx.configPath);\n const configuredProviders = await getConfiguredProviders();\n const providerFilter = options.provider?.trim();\n const models = (options.all ? getAllModels() : await getAvailableModels()).filter((m) =>\n providerFilter ? m.provider === providerFilter : true,\n );\n\n if (options.json) {\n console.log(\n JSON.stringify(\n {\n defaultModel: currentModelRef(config) ?? null,\n providers: configuredProviders,\n models: models.map((m) => ({\n id: modelRef(m.provider, m.id),\n name: m.name,\n provider: m.provider,\n authConfigured: configuredProviders.includes(m.provider),\n })),\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n console.log('\\n🤖 Models\\n');\n console.log('═'.repeat(60));\n\n console.log(`\\n📌 Current default model: ${currentModelRef(config) ?? 'Not set'}\\n`);\n\n const byProvider = new Map<string, typeof models>();\n for (const model of models) {\n const list = byProvider.get(model.provider) ?? [];\n list.push(model);\n byProvider.set(model.provider, list);\n }\n\n for (const [provider, providerModels] of byProvider) {\n const available = await isProviderConfigured(provider);\n console.log(` [${provider}] ${available ? colors.green('configured') : colors.gray('not configured')}`);\n for (const model of providerModels) {\n const badges: string[] = [];\n if (IMAGE_GENERATION_IDS.has(model.id)) badges.push('gen');\n if (model.input?.includes('image') || VISION_IDS.has(model.id)) badges.push('vision');\n const badgeStr = badges.length > 0 ? ` [${badges.join(', ')}]` : '';\n console.log(` ${available ? '✓' : '○'} ${modelRef(model.provider, model.id)}${badgeStr}`);\n }\n }\n\n console.log('\\nUsage:');\n console.log(' xopc models set openai/gpt-5.5');\n console.log(' xopc models auth login --provider anthropic');\n console.log(' xopc models auth paste-api-key --provider deepseek');\n}\n\nasync function runModelsStatus(options: { json?: boolean }): Promise<void> {\n const ctx = getContextWithOpts();\n const config = loadConfig(ctx.configPath);\n const providers = Array.from(new Set(getAllModels().map((m) => m.provider))).sort();\n const auth = [];\n for (const provider of providers) {\n const state = await getProviderAuthState(provider);\n if (state.authMode !== 'none') {\n auth.push({ provider, ...state });\n }\n }\n\n if (options.json) {\n console.log(JSON.stringify({ defaultModel: currentModelRef(config) ?? null, auth }, null, 2));\n return;\n }\n\n console.log('\\n🤖 Model status\\n');\n console.log(`Default: ${currentModelRef(config) ?? 'Not set'}`);\n console.log('\\nAuth:');\n if (auth.length === 0) {\n console.log(' No provider credentials configured.');\n return;\n }\n for (const entry of auth) {\n const status = entry.authStatus === 'connected' ? colors.green(entry.authStatus) : colors.yellow(entry.authStatus);\n console.log(` ${entry.provider}: ${status} (${entry.authMode})`);\n }\n}\n\nasync function runModelsSet(model: string): Promise<void> {\n const ctx = getContextWithOpts();\n const config = loadConfig(ctx.configPath);\n const resolved = resolveModel(model);\n const ref = modelRef(resolved.provider, resolved.id);\n setDefaultModel(config, ref);\n await saveConfig(config, ctx.configPath);\n console.log(`✅ Default model set: ${ref}`);\n}\n\nasync function runAuthList(options: ModelsAuthListOptions): Promise<void> {\n const resolver = new CredentialResolver();\n const profiles = (await resolver.listProfiles()).filter((profile) =>\n options.provider ? profile.provider === options.provider : true,\n );\n const oauthTokens = (await resolver.listOAuthTokens()).filter((token) =>\n options.provider ? token.provider === options.provider : true,\n );\n\n if (options.json) {\n console.log(JSON.stringify({ profiles, oauth: oauthTokens }, null, 2));\n return;\n }\n\n console.log('\\n🔐 Model auth\\n');\n if (profiles.length === 0 && oauthTokens.length === 0) {\n console.log(' No model credentials configured.');\n return;\n }\n for (const profile of profiles) {\n console.log(` ${profile.id} ${colors.blue('api-key')} ${profile.provider} ${profile.source}`);\n }\n for (const token of oauthTokens) {\n const expires = token.expiresAt ? ` expires ${new Date(token.expiresAt).toLocaleString()}` : '';\n console.log(` ${token.provider}:oauth ${colors.yellow('oauth')} ${token.hasAccess ? 'configured' : 'missing'}${expires}`);\n }\n}\n\nasync function runAuthPasteApiKey(provider: string): Promise<void> {\n if (!providerSupportsApiKey(provider)) {\n throw new Error(`Provider ${provider} does not support API key auth`);\n }\n const key = await input({\n message: `API key for ${provider}:`,\n validate: (value: string) => value.trim().length > 0 || 'Required',\n });\n await new CredentialResolver().saveApiKey(provider, key.trim(), { profileName: 'default' });\n console.log(`✅ API key saved for ${provider}`);\n}\n\nfunction resolveAuthMethod(provider: string, rawMethod?: string): 'oauth' | 'api-key' {\n if (rawMethod && rawMethod !== 'oauth' && rawMethod !== 'api-key') {\n throw new Error(`Unsupported auth method: ${rawMethod}`);\n }\n if (rawMethod === 'oauth' || rawMethod === 'api-key') return rawMethod;\n return providerSupportsOAuth(provider) ? 'oauth' : 'api-key';\n}\n\nasync function runAuthLogin(provider: string, options: ModelsAuthLoginOptions): Promise<void> {\n const method = resolveAuthMethod(provider, options.method);\n if (method === 'api-key') {\n await runAuthPasteApiKey(provider);\n } else {\n if (!providerSupportsOAuth(provider)) {\n throw new Error(`Provider ${provider} does not support OAuth`);\n }\n console.log(`\\n🔐 Starting ${getProviderDisplayName(provider)} OAuth login...`);\n await runCliOAuthLogin({ provider, onProgress: (message) => console.log(' →', message) });\n console.log(`✅ OAuth login successful for ${provider}`);\n }\n\n if (options.setDefault) {\n const first = getAllModels().find((model) => model.provider === provider);\n if (!first) throw new Error(`No models found for provider ${provider}`);\n await runModelsSet(modelRef(first.provider, first.id));\n }\n}\n\nasync function runAuthLogout(provider: string): Promise<void> {\n await new CredentialResolver().deleteProviderCredential(provider);\n console.log(`✅ Credentials removed for ${provider}`);\n}\n\nfunction attachModelsListOptions(command: Command): Command {\n return command\n .option('--json', 'Output as JSON', false)\n .option('--all, -a', 'Show all built-in models', false)\n .option('--provider <id>', 'Filter by provider id');\n}\n\nfunction createModelsCommand(_ctx: CLIContext): Command {\n const cmd = new Command('models')\n .description('List and manage models and model auth')\n .addHelpText(\n 'after',\n formatExamples([\n 'xopc models list',\n 'xopc models status',\n 'xopc models set openai/gpt-5.5',\n 'xopc models auth list',\n 'xopc models auth login --provider anthropic',\n 'xopc models auth paste-api-key --provider deepseek',\n ]),\n );\n\n attachModelsListOptions(cmd).action(async (options) => {\n await runModelsList(options);\n });\n\n attachModelsListOptions(cmd.command('list').description('List available models')).action(async (options) => {\n await runModelsList(options);\n });\n\n cmd\n .command('status')\n .description('Show default model and provider auth status')\n .option('--json', 'Output as JSON', false)\n .action(async (options: { json?: boolean }) => {\n await runModelsStatus(options);\n });\n\n cmd\n .command('set <model>')\n .description('Set the default model')\n .action(async (model: string) => {\n await runModelsSet(model);\n });\n\n const auth = cmd.command('auth').description('Manage model provider auth');\n\n auth\n .command('list')\n .description('List model auth credentials')\n .option('--provider <id>', 'Filter by provider id')\n .option('--json', 'Output as JSON', false)\n .action(async (options: ModelsAuthListOptions) => {\n await runAuthList(options);\n });\n\n auth\n .command('login')\n .description('Run provider auth flow')\n .requiredOption('--provider <id>', 'Provider id')\n .option('--method <method>', 'Auth method: oauth or api-key')\n .option('--set-default', 'Set the provider first model as default after login', false)\n .action(async (options: ModelsAuthLoginOptions & { provider: string }) => {\n await runAuthLogin(options.provider, options);\n });\n\n auth\n .command('paste-api-key')\n .description('Paste and save an API key')\n .requiredOption('--provider <id>', 'Provider id')\n .action(async (options: { provider: string }) => {\n await runAuthPasteApiKey(options.provider);\n });\n\n auth\n .command('logout')\n .description('Remove provider credentials')\n .requiredOption('--provider <id>', 'Provider id')\n .action(async (options: { provider: string }) => {\n await runAuthLogout(options.provider);\n });\n\n return cmd;\n}\n\nregister({\n id: 'models',\n name: 'models',\n description: 'List and manage models and model auth',\n factory: createModelsCommand,\n metadata: {\n category: 'utility',\n examples: ['xopc models list', 'xopc models status', 'xopc models auth list'],\n },\n});\n\nexport { createModelsCommand };\n"],"mappings":"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"}
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Catalog-driven model configuration for onboarding.
|
|
3
3
|
*/
|
|
4
4
|
import type { Config } from '../../../config/schema.js';
|
|
5
5
|
import type { CLIContext } from '../../registry.js';
|
|
6
|
-
/**
|
|
7
|
-
* Configure AI model provider and model
|
|
8
|
-
*/
|
|
9
6
|
export declare function setupModel(existingConfig: Config | null, ctx: CLIContext): Promise<Config>;
|