woopcode 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,6 +14,16 @@ Local commands that execute instantly without invoking the LLM.
14
14
  - **`/provider [name]`** (alias: `p`) - Show current provider or switch to another
15
15
  - Without arguments: Shows current provider and all available providers
16
16
  - With provider name: Switches to the specified provider (if configured)
17
+
18
+ - **`/login <provider> <api-key>`** - Login to a provider from within the app
19
+ - Example: `/login google YOUR_API_KEY`
20
+ - Validates the API key before saving
21
+ - Sets the provider as active
22
+
23
+ - **`/logout [provider]`** - Logout from a provider
24
+ - Without arguments: Logs out from current provider
25
+ - With provider name: Logs out from specified provider
26
+ - Automatically switches to another logged-in provider if available
17
27
 
18
28
  - **`/model`** (alias: `m`) - Show current model and available models
19
29
  - Currently read-only; model switching will be added in future versions
@@ -81,7 +81,7 @@ const providerCommand: SlashCommand = {
81
81
  })
82
82
  .join("\n");
83
83
 
84
- return `Current Provider: ${current}\n\nAvailable:\n${providers}`;
84
+ return `Current Provider: ${current}\n\nAvailable:\n${providers}\n\nTip: Use /login or /logout to manage authentication`;
85
85
  }
86
86
 
87
87
  const newProvider = args[0];
@@ -97,7 +97,7 @@ const providerCommand: SlashCommand = {
97
97
 
98
98
  const providerConfig = config.providers[newProvider];
99
99
  if (!providerConfig || !providerConfig.apiKey) {
100
- return `Provider "${newProvider}" not configured.\nRun: woopcode providers login -p ${newProvider}`;
100
+ return `Provider "${newProvider}" not configured.\nUse: /login ${newProvider} <api-key>`;
101
101
  }
102
102
 
103
103
  config.defaultProvider = newProvider;
@@ -134,6 +134,93 @@ const modelCommand: SlashCommand = {
134
134
  },
135
135
  };
136
136
 
137
+ const loginCommand: SlashCommand = {
138
+ name: "login",
139
+ description: "Login to a provider",
140
+ category: "configuration",
141
+ usage: "/login <provider> <api-key>",
142
+
143
+ async execute(context, args) {
144
+ if (args.length < 2) {
145
+ return `Usage: /login <provider> <api-key>\nExample: /login google YOUR_API_KEY`;
146
+ }
147
+
148
+ const provider = args[0];
149
+ const apiKey = args.slice(1).join(" "); // Allow API keys with spaces
150
+
151
+ const config = await getConfig();
152
+
153
+ if (!config.providers[provider]) {
154
+ const available = Object.keys(config.providers);
155
+ return `Unknown provider "${provider}".\nAvailable: ${available.join(", ")}`;
156
+ }
157
+
158
+ // Validate API key
159
+ const { loginProvider } = await import("../../config/authProvider");
160
+ const isValid = await loginProvider(provider, apiKey);
161
+
162
+ if (!isValid) {
163
+ return `Invalid API key for ${provider}.\nPlease check your API key and try again.`;
164
+ }
165
+
166
+ // Save the API key
167
+ config.providers[provider].apiKey = apiKey;
168
+ config.defaultProvider = provider;
169
+ await saveConfig(config);
170
+
171
+ return `Successfully logged in to ${provider}!\nThis is now your active provider.`;
172
+ },
173
+ };
174
+
175
+ const logoutCommand: SlashCommand = {
176
+ name: "logout",
177
+ description: "Logout from a provider",
178
+ category: "configuration",
179
+ usage: "/logout [provider]",
180
+
181
+ async execute(context, args) {
182
+ const config = await getConfig();
183
+
184
+ // If no provider specified, logout from current
185
+ const provider = args[0] || config.defaultProvider;
186
+
187
+ if (!config.providers[provider]) {
188
+ const available = Object.keys(config.providers);
189
+ return `Unknown provider "${provider}".\nAvailable: ${available.join(", ")}`;
190
+ }
191
+
192
+ const providerConfig = config.providers[provider];
193
+ if (!providerConfig?.apiKey) {
194
+ return `Already logged out from ${provider}.`;
195
+ }
196
+
197
+ // Remove API key
198
+ delete config.providers[provider].apiKey;
199
+
200
+ // If logging out from default provider, clear default
201
+ if (config.defaultProvider === provider) {
202
+ // Find another logged-in provider
203
+ const otherProvider = Object.entries(config.providers).find(
204
+ ([name, details]: [string, any]) => name !== provider && details.apiKey
205
+ );
206
+
207
+ if (otherProvider) {
208
+ config.defaultProvider = otherProvider[0];
209
+ } else {
210
+ config.defaultProvider = "";
211
+ }
212
+ }
213
+
214
+ await saveConfig(config);
215
+
216
+ const nextProvider = config.defaultProvider
217
+ ? `\nActive provider: ${config.defaultProvider}`
218
+ : "\nNo providers logged in. Use /login to authenticate.";
219
+
220
+ return `Logged out from ${provider}.${nextProvider}`;
221
+ },
222
+ };
223
+
137
224
  // ==================== WORKSPACE COMMANDS ====================
138
225
 
139
226
  const workspaceCommand: SlashCommand = {
@@ -232,6 +319,8 @@ export function registerCommands() {
232
319
  registry.register(newCommand);
233
320
  registry.register(exitCommand);
234
321
  registry.register(providerCommand);
322
+ registry.register(loginCommand);
323
+ registry.register(logoutCommand);
235
324
  registry.register(modelCommand);
236
325
  registry.register(workspaceCommand);
237
326
  registry.register(statusCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "woopcode",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "An autonomous AI coding assistant built for the terminal",
5
5
  "license": "MIT",
6
6
  "author": {