codowave 0.1.8 → 0.1.9

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/dist/index.js CHANGED
@@ -1,18 +1,31 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropNames = Object.getOwnPropertyNames;
3
- var __esm = (fn, res) => function __init() {
4
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
5
- };
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
1
+ // src/index.ts
2
+ import { Command as Command7 } from "commander";
10
3
 
11
4
  // src/config.ts
12
5
  import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
13
6
  import { join } from "path";
14
7
  import { homedir } from "os";
15
8
  import { z } from "zod";
9
+ var AIProviderSchema = z.object({
10
+ provider: z.enum(["openai", "anthropic", "minimax", "ollama", "custom"]),
11
+ apiKey: z.string().min(1),
12
+ model: z.string().default(""),
13
+ baseUrl: z.string().url().optional()
14
+ });
15
+ var ConfigSchema = z.object({
16
+ apiKey: z.string().min(1),
17
+ apiUrl: z.string().url().default("https://api.codowave.com"),
18
+ repos: z.array(
19
+ z.object({
20
+ owner: z.string(),
21
+ name: z.string(),
22
+ id: z.string().optional()
23
+ })
24
+ ).default([]),
25
+ ai: AIProviderSchema.optional()
26
+ });
27
+ var CONFIG_DIR = join(homedir(), ".codowave");
28
+ var CONFIG_FILE = join(CONFIG_DIR, "config.json");
16
29
  function readConfig() {
17
30
  if (!existsSync(CONFIG_FILE)) {
18
31
  return null;
@@ -61,32 +74,11 @@ function updateConfig(updates) {
61
74
  function getConfigPath() {
62
75
  return CONFIG_FILE;
63
76
  }
64
- var AIProviderSchema, ConfigSchema, CONFIG_DIR, CONFIG_FILE;
65
- var init_config = __esm({
66
- "src/config.ts"() {
67
- "use strict";
68
- AIProviderSchema = z.object({
69
- provider: z.enum(["openai", "anthropic", "minimax", "ollama", "custom"]),
70
- apiKey: z.string().min(1),
71
- model: z.string().default(""),
72
- baseUrl: z.string().url().optional()
73
- });
74
- ConfigSchema = z.object({
75
- apiKey: z.string().min(1),
76
- apiUrl: z.string().url().default("https://api.codowave.com"),
77
- repos: z.array(
78
- z.object({
79
- owner: z.string(),
80
- name: z.string(),
81
- id: z.string().optional()
82
- })
83
- ).default([]),
84
- ai: AIProviderSchema.optional()
85
- });
86
- CONFIG_DIR = join(homedir(), ".codowave");
87
- CONFIG_FILE = join(CONFIG_DIR, "config.json");
88
- }
89
- });
77
+
78
+ // src/commands/init.tsx
79
+ import { Command } from "commander";
80
+ import pc2 from "picocolors";
81
+ import { render } from "ink";
90
82
 
91
83
  // src/components/init/GithubAppStep.tsx
92
84
  import { useState, useEffect } from "react";
@@ -98,277 +90,253 @@ import {
98
90
  import Spinner from "ink-spinner";
99
91
  import pc from "picocolors";
100
92
  import { jsx, jsxs } from "react/jsx-runtime";
101
- var GithubAppStep;
102
- var init_GithubAppStep = __esm({
103
- "src/components/init/GithubAppStep.tsx"() {
104
- "use strict";
105
- GithubAppStep = ({ apiUrl, onComplete, onCancel }) => {
106
- const [step, setStep] = useState("api-key");
107
- const [apiKey, setApiKey] = useState("");
108
- const [repos, setRepos] = useState([]);
109
- const [selectedRepos, setSelectedRepos] = useState(/* @__PURE__ */ new Set());
110
- const [currentSelection, setCurrentSelection] = useState(0);
111
- const [loading, setLoading] = useState(false);
112
- const [error, setError] = useState(null);
113
- useEffect(() => {
114
- if (step === "repos" && apiKey && repos.length === 0 && !loading) {
115
- fetchRepos();
93
+ var GithubAppStep = ({ apiUrl, onComplete, onCancel }) => {
94
+ const [step, setStep] = useState("api-key");
95
+ const [apiKey, setApiKey] = useState("");
96
+ const [repos, setRepos] = useState([]);
97
+ const [selectedRepos, setSelectedRepos] = useState(/* @__PURE__ */ new Set());
98
+ const [currentSelection, setCurrentSelection] = useState(0);
99
+ const [loading, setLoading] = useState(false);
100
+ const [error, setError] = useState(null);
101
+ useEffect(() => {
102
+ if (step === "repos" && apiKey && repos.length === 0 && !loading) {
103
+ fetchRepos();
104
+ }
105
+ }, [step, apiKey]);
106
+ async function fetchRepos() {
107
+ setLoading(true);
108
+ setError(null);
109
+ try {
110
+ const response = await fetch(`${apiUrl}/api/v1/repos`, {
111
+ headers: {
112
+ Authorization: `Bearer ${apiKey}`,
113
+ "Content-Type": "application/json"
116
114
  }
117
- }, [step, apiKey]);
118
- async function fetchRepos() {
119
- setLoading(true);
120
- setError(null);
121
- try {
122
- const response = await fetch(`${apiUrl}/api/v1/repos`, {
123
- headers: {
124
- Authorization: `Bearer ${apiKey}`,
125
- "Content-Type": "application/json"
126
- }
127
- });
128
- if (!response.ok) {
129
- if (response.status === 401) {
130
- throw new Error("Invalid API key. Please check and try again.");
131
- }
132
- throw new Error(`Failed to fetch repositories: ${response.status}`);
133
- }
134
- const data = await response.json();
135
- const fetchedRepos = data.repos || data.repositories || [];
136
- setRepos(fetchedRepos);
137
- if (fetchedRepos.length > 0) {
138
- const allIndices = /* @__PURE__ */ new Set();
139
- for (let i = 0; i < fetchedRepos.length; i++) {
140
- allIndices.add(i);
141
- }
142
- setSelectedRepos(allIndices);
143
- }
144
- } catch (err) {
145
- setError(err instanceof Error ? err.message : "Failed to fetch repositories");
146
- } finally {
147
- setLoading(false);
115
+ });
116
+ if (!response.ok) {
117
+ if (response.status === 401) {
118
+ throw new Error("Invalid API key. Please check and try again.");
148
119
  }
120
+ throw new Error(`Failed to fetch repositories: ${response.status}`);
149
121
  }
150
- function handleApiKeySubmit() {
151
- if (!apiKey.trim()) {
152
- setError("API key cannot be empty");
153
- return;
122
+ const data = await response.json();
123
+ const fetchedRepos = data.repos || data.repositories || [];
124
+ setRepos(fetchedRepos);
125
+ if (fetchedRepos.length > 0) {
126
+ const allIndices = /* @__PURE__ */ new Set();
127
+ for (let i = 0; i < fetchedRepos.length; i++) {
128
+ allIndices.add(i);
154
129
  }
155
- setError(null);
156
- setStep("repos");
130
+ setSelectedRepos(allIndices);
157
131
  }
158
- function handleConfirm() {
159
- const selected = Array.from(selectedRepos).map((i) => repos[i]).filter((repo) => repo !== void 0);
160
- onComplete(apiKey, selected);
132
+ } catch (err) {
133
+ setError(err instanceof Error ? err.message : "Failed to fetch repositories");
134
+ } finally {
135
+ setLoading(false);
136
+ }
137
+ }
138
+ function handleApiKeySubmit() {
139
+ if (!apiKey.trim()) {
140
+ setError("API key cannot be empty");
141
+ return;
142
+ }
143
+ setError(null);
144
+ setStep("repos");
145
+ }
146
+ function handleConfirm() {
147
+ const selected = Array.from(selectedRepos).map((i) => repos[i]).filter((repo) => repo !== void 0);
148
+ onComplete(apiKey, selected);
149
+ }
150
+ function handleGoBack() {
151
+ setStep("api-key");
152
+ setError(null);
153
+ }
154
+ useInput((input, key) => {
155
+ if (step === "api-key") {
156
+ if (key.return) {
157
+ handleApiKeySubmit();
158
+ return;
161
159
  }
162
- function handleGoBack() {
163
- setStep("api-key");
160
+ if (key.escape) {
161
+ onCancel();
162
+ return;
163
+ }
164
+ if (key.backspace || input === "\b") {
165
+ setApiKey((prev) => prev.slice(0, -1));
164
166
  setError(null);
167
+ return;
165
168
  }
166
- useInput((input, key) => {
167
- if (step === "api-key") {
168
- if (key.return) {
169
- handleApiKeySubmit();
170
- return;
171
- }
172
- if (key.escape) {
173
- onCancel();
174
- return;
175
- }
176
- if (key.backspace || input === "\b") {
177
- setApiKey((prev) => prev.slice(0, -1));
178
- setError(null);
179
- return;
180
- }
181
- if (input && !key.ctrl && !key.meta) {
182
- setApiKey((prev) => prev + input);
183
- setError(null);
184
- return;
185
- }
186
- } else if (step === "repos") {
187
- if (key.escape) {
188
- handleGoBack();
189
- return;
190
- }
191
- if (key.return) {
192
- handleConfirm();
193
- return;
194
- }
195
- if (input === " ") {
196
- toggleRepo(currentSelection);
197
- return;
198
- }
199
- if (key.upArrow) {
200
- setCurrentSelection((prev) => Math.max(0, prev - 1));
201
- return;
202
- }
203
- if (key.downArrow) {
204
- setCurrentSelection((prev) => Math.min(repos.length - 1, prev + 1));
205
- return;
206
- }
207
- if (input === "a" || input === "A") {
208
- const allIndices = /* @__PURE__ */ new Set();
209
- for (let i = 0; i < repos.length; i++) {
210
- allIndices.add(i);
211
- }
212
- setSelectedRepos(allIndices);
213
- return;
214
- }
215
- if (input === "n" || input === "N") {
216
- setSelectedRepos(/* @__PURE__ */ new Set());
217
- return;
218
- }
219
- }
220
- });
221
- function toggleRepo(index) {
222
- const newSelected = new Set(selectedRepos);
223
- if (newSelected.has(index)) {
224
- newSelected.delete(index);
225
- } else {
226
- newSelected.add(index);
227
- }
228
- setSelectedRepos(newSelected);
169
+ if (input && !key.ctrl && !key.meta) {
170
+ setApiKey((prev) => prev + input);
171
+ setError(null);
172
+ return;
229
173
  }
230
- if (step === "api-key") {
231
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingY: 1, children: [
232
- /* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "\u2550\u2550\u2550 GitHub App Setup \u2550\u2550\u2550" }) }),
233
- /* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { children: "Enter your Codowave API key:" }) }),
234
- /* @__PURE__ */ jsxs(Box, { children: [
235
- /* @__PURE__ */ jsx(Text, { color: "gray", children: "> " }),
236
- /* @__PURE__ */ jsx(Text, { children: apiKey }),
237
- /* @__PURE__ */ jsx(Text, { color: "cyan", children: "_" })
238
- ] }),
239
- error && /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { color: "red", children: pc.red("\u2716 " + error) }) }),
240
- /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
241
- "Press ",
242
- /* @__PURE__ */ jsx(Text, { bold: true, children: "Enter" }),
243
- " to continue, ",
244
- /* @__PURE__ */ jsx(Text, { bold: true, children: "Esc" }),
245
- " to cancel"
246
- ] }) })
247
- ] });
174
+ } else if (step === "repos") {
175
+ if (key.escape) {
176
+ handleGoBack();
177
+ return;
248
178
  }
249
- if (step === "repos") {
250
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingY: 1, children: [
251
- /* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "\u2550\u2550\u2550 Select Repositories \u2550\u2550\u2550" }) }),
252
- loading && /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
253
- /* @__PURE__ */ jsx(Spinner, { type: "dots" }),
254
- " Loading repositories..."
255
- ] }) }),
256
- error && /* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { color: "red", children: pc.red("\u2716 " + error) }) }),
257
- !loading && !error && repos.length === 0 && /* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { color: "yellow", children: "No repositories found for this API key." }) }),
258
- !loading && repos.length > 0 && /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginBottom: 1, children: repos.map((repo, index) => /* @__PURE__ */ jsxs(Box, { children: [
259
- /* @__PURE__ */ jsx(Text, { children: index === currentSelection ? " > " : " " }),
260
- /* @__PURE__ */ jsxs(Text, { color: selectedRepos.has(index) ? "green" : "gray", children: [
261
- "[",
262
- selectedRepos.has(index) ? "\u2713" : " ",
263
- "]"
264
- ] }),
265
- /* @__PURE__ */ jsx(Text, { children: " " }),
266
- /* @__PURE__ */ jsx(Text, { bold: index === currentSelection, children: /* @__PURE__ */ jsxs(Text, { dimColor: !selectedRepos.has(index), children: [
267
- repo.owner,
268
- "/",
269
- repo.name
270
- ] }) })
271
- ] }, index)) }),
272
- !loading && repos.length > 0 && /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
273
- /* @__PURE__ */ jsx(Text, { bold: true, children: "\u2191/\u2193" }),
274
- " navigate | ",
275
- /* @__PURE__ */ jsx(Text, { bold: true, children: "Space" }),
276
- " toggle | ",
277
- /* @__PURE__ */ jsx(Text, { bold: true, children: "A" }),
278
- " all | ",
279
- /* @__PURE__ */ jsx(Text, { bold: true, children: "N" }),
280
- " none"
281
- ] }) }),
282
- /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
283
- "Selected: ",
284
- /* @__PURE__ */ jsx(Text, { bold: true, color: "green", children: selectedRepos.size }),
285
- " / ",
286
- repos.length,
287
- " repos | ",
288
- /* @__PURE__ */ jsx(Text, { bold: true, children: "Enter" }),
289
- " confirm | ",
290
- /* @__PURE__ */ jsx(Text, { bold: true, children: "Esc" }),
291
- " back"
292
- ] }) })
293
- ] });
179
+ if (key.return) {
180
+ handleConfirm();
181
+ return;
294
182
  }
295
- return null;
296
- };
297
- }
298
- });
299
-
300
- // src/commands/init.tsx
301
- var init_exports = {};
302
- __export(init_exports, {
303
- initCommand: () => initCommand
304
- });
305
- import { Command } from "commander";
306
- import pc2 from "picocolors";
307
- import { render } from "ink";
308
- import { jsx as jsx2 } from "react/jsx-runtime";
309
- var initCommand;
310
- var init_init = __esm({
311
- "src/commands/init.tsx"() {
312
- "use strict";
313
- init_config();
314
- init_GithubAppStep();
315
- initCommand = new Command("init").description("Initialize Codowave and connect your GitHub repositories").action(async () => {
316
- const existingConfig = readConfig();
317
- const defaultApiUrl = "https://api.codowave.com";
318
- const apiUrl = existingConfig?.apiUrl || defaultApiUrl;
319
- if (existingConfig?.apiKey) {
320
- console.log(pc2.yellow("\n\u26A0 Codowave is already initialized.\n"));
321
- console.log(` API URL: ${pc2.cyan(existingConfig.apiUrl)}`);
322
- console.log(` Config: ${getConfigPath()}`);
323
- console.log(pc2.gray("\n Run this command again to reconfigure.\n"));
183
+ if (input === " ") {
184
+ toggleRepo(currentSelection);
324
185
  return;
325
186
  }
326
- let wizardComplete = false;
327
- let capturedApiKey = "";
328
- let capturedRepos = [];
329
- const { waitUntilExit } = render(
330
- /* @__PURE__ */ jsx2(
331
- GithubAppStep,
332
- {
333
- apiUrl,
334
- onComplete: (apiKey, repos) => {
335
- capturedApiKey = apiKey;
336
- capturedRepos = repos;
337
- wizardComplete = true;
338
- },
339
- onCancel: () => {
340
- process.exit(0);
341
- }
342
- }
343
- )
344
- );
345
- await waitUntilExit();
346
- if (!wizardComplete) {
187
+ if (key.upArrow) {
188
+ setCurrentSelection((prev) => Math.max(0, prev - 1));
189
+ return;
190
+ }
191
+ if (key.downArrow) {
192
+ setCurrentSelection((prev) => Math.min(repos.length - 1, prev + 1));
193
+ return;
194
+ }
195
+ if (input === "a" || input === "A") {
196
+ const allIndices = /* @__PURE__ */ new Set();
197
+ for (let i = 0; i < repos.length; i++) {
198
+ allIndices.add(i);
199
+ }
200
+ setSelectedRepos(allIndices);
201
+ return;
202
+ }
203
+ if (input === "n" || input === "N") {
204
+ setSelectedRepos(/* @__PURE__ */ new Set());
347
205
  return;
348
206
  }
349
- writeConfig({
350
- apiKey: capturedApiKey,
207
+ }
208
+ });
209
+ function toggleRepo(index) {
210
+ const newSelected = new Set(selectedRepos);
211
+ if (newSelected.has(index)) {
212
+ newSelected.delete(index);
213
+ } else {
214
+ newSelected.add(index);
215
+ }
216
+ setSelectedRepos(newSelected);
217
+ }
218
+ if (step === "api-key") {
219
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingY: 1, children: [
220
+ /* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "\u2550\u2550\u2550 GitHub App Setup \u2550\u2550\u2550" }) }),
221
+ /* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { children: "Enter your Codowave API key:" }) }),
222
+ /* @__PURE__ */ jsxs(Box, { children: [
223
+ /* @__PURE__ */ jsx(Text, { color: "gray", children: "> " }),
224
+ /* @__PURE__ */ jsx(Text, { children: apiKey }),
225
+ /* @__PURE__ */ jsx(Text, { color: "cyan", children: "_" })
226
+ ] }),
227
+ error && /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { color: "red", children: pc.red("\u2716 " + error) }) }),
228
+ /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
229
+ "Press ",
230
+ /* @__PURE__ */ jsx(Text, { bold: true, children: "Enter" }),
231
+ " to continue, ",
232
+ /* @__PURE__ */ jsx(Text, { bold: true, children: "Esc" }),
233
+ " to cancel"
234
+ ] }) })
235
+ ] });
236
+ }
237
+ if (step === "repos") {
238
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingY: 1, children: [
239
+ /* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "\u2550\u2550\u2550 Select Repositories \u2550\u2550\u2550" }) }),
240
+ loading && /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
241
+ /* @__PURE__ */ jsx(Spinner, { type: "dots" }),
242
+ " Loading repositories..."
243
+ ] }) }),
244
+ error && /* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { color: "red", children: pc.red("\u2716 " + error) }) }),
245
+ !loading && !error && repos.length === 0 && /* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { color: "yellow", children: "No repositories found for this API key." }) }),
246
+ !loading && repos.length > 0 && /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginBottom: 1, children: repos.map((repo, index) => /* @__PURE__ */ jsxs(Box, { children: [
247
+ /* @__PURE__ */ jsx(Text, { children: index === currentSelection ? " > " : " " }),
248
+ /* @__PURE__ */ jsxs(Text, { color: selectedRepos.has(index) ? "green" : "gray", children: [
249
+ "[",
250
+ selectedRepos.has(index) ? "\u2713" : " ",
251
+ "]"
252
+ ] }),
253
+ /* @__PURE__ */ jsx(Text, { children: " " }),
254
+ /* @__PURE__ */ jsx(Text, { bold: index === currentSelection, children: /* @__PURE__ */ jsxs(Text, { dimColor: !selectedRepos.has(index), children: [
255
+ repo.owner,
256
+ "/",
257
+ repo.name
258
+ ] }) })
259
+ ] }, index)) }),
260
+ !loading && repos.length > 0 && /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
261
+ /* @__PURE__ */ jsx(Text, { bold: true, children: "\u2191/\u2193" }),
262
+ " navigate | ",
263
+ /* @__PURE__ */ jsx(Text, { bold: true, children: "Space" }),
264
+ " toggle | ",
265
+ /* @__PURE__ */ jsx(Text, { bold: true, children: "A" }),
266
+ " all | ",
267
+ /* @__PURE__ */ jsx(Text, { bold: true, children: "N" }),
268
+ " none"
269
+ ] }) }),
270
+ /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
271
+ "Selected: ",
272
+ /* @__PURE__ */ jsx(Text, { bold: true, color: "green", children: selectedRepos.size }),
273
+ " / ",
274
+ repos.length,
275
+ " repos | ",
276
+ /* @__PURE__ */ jsx(Text, { bold: true, children: "Enter" }),
277
+ " confirm | ",
278
+ /* @__PURE__ */ jsx(Text, { bold: true, children: "Esc" }),
279
+ " back"
280
+ ] }) })
281
+ ] });
282
+ }
283
+ return null;
284
+ };
285
+
286
+ // src/commands/init.tsx
287
+ import { jsx as jsx2 } from "react/jsx-runtime";
288
+ var initCommand = new Command("init").description("Initialize Codowave and connect your GitHub repositories").action(async () => {
289
+ const existingConfig = readConfig();
290
+ const defaultApiUrl = "https://api.codowave.com";
291
+ const apiUrl = existingConfig?.apiUrl || defaultApiUrl;
292
+ if (existingConfig?.apiKey) {
293
+ console.log(pc2.yellow("\n\u26A0 Codowave is already initialized.\n"));
294
+ console.log(` API URL: ${pc2.cyan(existingConfig.apiUrl)}`);
295
+ console.log(` Config: ${getConfigPath()}`);
296
+ console.log(pc2.gray("\n Run this command again to reconfigure.\n"));
297
+ return;
298
+ }
299
+ let wizardComplete = false;
300
+ let capturedApiKey = "";
301
+ let capturedRepos = [];
302
+ const { waitUntilExit } = render(
303
+ /* @__PURE__ */ jsx2(
304
+ GithubAppStep,
305
+ {
351
306
  apiUrl,
352
- repos: capturedRepos
353
- });
354
- console.log(pc2.green("\n\u2713 Initialization complete!"));
355
- console.log(`
307
+ onComplete: (apiKey, repos) => {
308
+ capturedApiKey = apiKey;
309
+ capturedRepos = repos;
310
+ wizardComplete = true;
311
+ },
312
+ onCancel: () => {
313
+ process.exit(0);
314
+ }
315
+ }
316
+ )
317
+ );
318
+ await waitUntilExit();
319
+ if (!wizardComplete) {
320
+ return;
321
+ }
322
+ writeConfig({
323
+ apiKey: capturedApiKey,
324
+ apiUrl,
325
+ repos: capturedRepos
326
+ });
327
+ console.log(pc2.green("\n\u2713 Initialization complete!"));
328
+ console.log(`
356
329
  Config saved to: ${pc2.cyan(getConfigPath())}`);
357
- console.log(` API URL: ${pc2.cyan(apiUrl)}`);
358
- console.log(` Repositories: ${pc2.bold(capturedRepos.length)} configured
330
+ console.log(` API URL: ${pc2.cyan(apiUrl)}`);
331
+ console.log(` Repositories: ${pc2.bold(capturedRepos.length)} configured
359
332
  `);
360
- console.log(pc2.gray(" Run ") + pc2.bold("codowave run") + pc2.gray(" to start coding!\n"));
361
- });
362
- }
333
+ console.log(pc2.gray(" Run ") + pc2.bold("codowave run") + pc2.gray(" to start coding!\n"));
363
334
  });
364
335
 
365
336
  // src/commands/run.ts
366
- var run_exports = {};
367
- __export(run_exports, {
368
- runCommand: () => runCommand
369
- });
370
337
  import { Command as Command2 } from "commander";
371
338
  import pc3 from "picocolors";
339
+ var demoRuns = /* @__PURE__ */ new Map();
372
340
  function parseIssue(input) {
373
341
  const urlMatch = input.match(/github\.com\/([^/]+)\/([^/]+)\/issues\/(\d+)/);
374
342
  if (urlMatch && urlMatch[1] && urlMatch[2] && urlMatch[3]) {
@@ -479,79 +447,67 @@ function streamDemoRun(run) {
479
447
  process.exit(1);
480
448
  });
481
449
  }
482
- var demoRuns, runCommand;
483
- var init_run = __esm({
484
- "src/commands/run.ts"() {
485
- "use strict";
486
- init_config();
487
- demoRuns = /* @__PURE__ */ new Map();
488
- runCommand = new Command2("run").description("Trigger Codowave to process a GitHub issue").argument("<issue>", "GitHub issue number, URL (https://github.com/owner/repo/issues/123), or owner/repo#123").option("-r, --repo <owner/repo>", "Target repository (e.g. owner/repo)").option("-s, --stream", "Stream run progress (SSE)", false).action(async (_issueArg, _options) => {
489
- try {
490
- const parsed = parseIssue(_issueArg);
491
- if (!parsed) {
492
- console.error(pc3.red("Invalid issue format. Use:"));
493
- console.error(" - Issue number: 123");
494
- console.error(" - Full URL: https://github.com/owner/repo/issues/123");
495
- console.error(" - Short form: owner/repo#123");
496
- process.exit(1);
497
- }
498
- if (_options.repo) {
499
- const parts = _options.repo.split("/");
500
- const owner = parts[0] || "";
501
- const repo = parts[1] || "";
502
- parsed.owner = owner;
503
- parsed.repo = repo;
504
- }
505
- let config = null;
506
- try {
507
- config = readConfig();
508
- } catch {
509
- }
510
- if (config && config.apiKey && config.repos.length > 0) {
511
- console.log(pc3.blue("Connecting to Codowave API..."));
512
- if (!parsed.owner || !parsed.repo) {
513
- console.error(pc3.red("Repository required. Use -r option or include in issue URL."));
514
- process.exit(1);
515
- }
516
- const runId = await triggerRun(config, parsed);
517
- console.log(pc3.green(`\u2713 Run triggered: ${runId}`));
518
- if (_options.stream) {
519
- console.log(pc3.blue("\nStreaming run progress..."));
520
- } else {
521
- console.log(pc3.gray(`
450
+ var runCommand = new Command2("run").description("Trigger Codowave to process a GitHub issue").argument("<issue>", "GitHub issue number, URL (https://github.com/owner/repo/issues/123), or owner/repo#123").option("-r, --repo <owner/repo>", "Target repository (e.g. owner/repo)").option("-s, --stream", "Stream run progress (SSE)", false).action(async (_issueArg, _options) => {
451
+ try {
452
+ const parsed = parseIssue(_issueArg);
453
+ if (!parsed) {
454
+ console.error(pc3.red("Invalid issue format. Use:"));
455
+ console.error(" - Issue number: 123");
456
+ console.error(" - Full URL: https://github.com/owner/repo/issues/123");
457
+ console.error(" - Short form: owner/repo#123");
458
+ process.exit(1);
459
+ }
460
+ if (_options.repo) {
461
+ const parts = _options.repo.split("/");
462
+ const owner = parts[0] || "";
463
+ const repo = parts[1] || "";
464
+ parsed.owner = owner;
465
+ parsed.repo = repo;
466
+ }
467
+ let config = null;
468
+ try {
469
+ config = readConfig();
470
+ } catch {
471
+ }
472
+ if (config && config.apiKey && config.repos.length > 0) {
473
+ console.log(pc3.blue("Connecting to Codowave API..."));
474
+ if (!parsed.owner || !parsed.repo) {
475
+ console.error(pc3.red("Repository required. Use -r option or include in issue URL."));
476
+ process.exit(1);
477
+ }
478
+ const runId = await triggerRun(config, parsed);
479
+ console.log(pc3.green(`\u2713 Run triggered: ${runId}`));
480
+ if (_options.stream) {
481
+ console.log(pc3.blue("\nStreaming run progress..."));
482
+ } else {
483
+ console.log(pc3.gray(`
522
484
  Run started. Use \`codowave status ${runId}\` to check progress.`));
523
- }
524
- } else {
525
- console.log(pc3.yellow("\u26A0 No config found. Running in demo mode.\n"));
526
- const run = createDemoRun(parsed);
527
- if (_options.stream || !process.stdout.isTTY) {
528
- streamDemoRun(run);
529
- } else {
530
- console.log(pc3.green(`\u2713 Run started: ${run.id}`));
531
- console.log(pc3.gray(`
485
+ }
486
+ } else {
487
+ console.log(pc3.yellow("\u26A0 No config found. Running in demo mode.\n"));
488
+ const run = createDemoRun(parsed);
489
+ if (_options.stream || !process.stdout.isTTY) {
490
+ streamDemoRun(run);
491
+ } else {
492
+ console.log(pc3.green(`\u2713 Run started: ${run.id}`));
493
+ console.log(pc3.gray(`
532
494
  Use \`codowave status ${run.id}\` to check progress.`));
533
- console.log(pc3.gray(`Use \`codowave logs ${run.id} -f\` to follow logs.`));
534
- }
535
- }
536
- } catch (err) {
537
- const message = err instanceof Error ? err.message : String(err);
538
- console.error(pc3.red(`
495
+ console.log(pc3.gray(`Use \`codowave logs ${run.id} -f\` to follow logs.`));
496
+ }
497
+ }
498
+ } catch (err) {
499
+ const message = err instanceof Error ? err.message : String(err);
500
+ console.error(pc3.red(`
539
501
  \u2716 Error: ${message}
540
502
  `));
541
- process.exit(1);
542
- }
543
- });
503
+ process.exit(1);
544
504
  }
545
505
  });
546
506
 
547
507
  // src/commands/status.ts
548
- var status_exports = {};
549
- __export(status_exports, {
550
- getRun: () => getRun,
551
- statusCommand: () => statusCommand
552
- });
553
508
  import { Command as Command3 } from "commander";
554
509
  import pc4 from "picocolors";
510
+ var demoRuns2 = /* @__PURE__ */ new Map();
555
511
  function initDemoData() {
556
512
  if (demoRuns2.size === 0) {
557
513
  const demoRun = {
@@ -645,345 +601,286 @@ function formatDuration(startedAt, completedAt) {
645
601
  const remainingMinutes = minutes % 60;
646
602
  return `${hours}h ${remainingMinutes}m`;
647
603
  }
648
- var demoRuns2, statusCommand;
649
- var init_status = __esm({
650
- "src/commands/status.ts"() {
651
- "use strict";
652
- init_config();
653
- demoRuns2 = /* @__PURE__ */ new Map();
654
- statusCommand = new Command3("status").description("Show the status of a Codowave run").argument("[run-id]", "Run ID (defaults to latest)").option("-r, --repo <owner/repo>", "Filter by repository").action(async (_runId, _options) => {
655
- try {
656
- let config;
657
- try {
658
- config = readConfig();
659
- } catch {
660
- }
661
- const run = getRun(_runId);
662
- if (!run) {
663
- console.log(pc4.yellow("No runs found. Run `codowave run <issue>` to start a new run."));
664
- return;
665
- }
666
- if (_options?.repo && run.repo !== _options.repo) {
667
- console.log(pc4.yellow("No run found for repository " + _options.repo));
668
- return;
669
- }
670
- console.log(pc4.bold("\n=== Run Status ===\n"));
671
- console.log(pc4.bold("ID: ") + run.id);
672
- console.log(pc4.bold("Repo: ") + run.repo);
673
- console.log(pc4.bold("Issue: ") + run.issue);
674
- console.log(pc4.bold("Status: ") + formatStatus(run.status));
675
- console.log(pc4.bold("Branch: ") + (run.branchName || pc4.gray("(none)")));
676
- if (run.prNumber) {
677
- console.log(pc4.bold("PR: ") + "#" + run.prNumber + " - " + (run.prTitle || ""));
678
- }
679
- if (run.startedAt) {
680
- console.log(pc4.bold("Started: ") + new Date(run.startedAt).toLocaleString());
681
- }
682
- if (run.completedAt) {
683
- console.log(pc4.bold("Duration: ") + formatDuration(run.startedAt, run.completedAt));
684
- } else if (run.startedAt) {
685
- console.log(pc4.bold("Duration: ") + pc4.blue("running... ") + formatDuration(run.startedAt));
686
- }
687
- if (run.errorMessage) {
688
- console.log(pc4.bold("Error: ") + pc4.red(run.errorMessage));
689
- }
690
- console.log(pc4.bold("\n=== Stages ===\n"));
691
- for (const stage of run.stages) {
692
- const statusIcon = formatStageStatus(stage.status);
693
- const statusText = pc4.bold("[" + stage.status + "]");
694
- console.log(" " + statusIcon + " " + pc4.bold(stage.name.padEnd(20)) + " " + statusText);
695
- }
696
- console.log("");
697
- } catch (err) {
698
- const message = err instanceof Error ? err.message : String(err);
699
- console.error(pc4.red("\n=== Error: " + message + " ===\n"));
700
- process.exit(1);
701
- }
702
- });
604
+ var statusCommand = new Command3("status").description("Show the status of a Codowave run").argument("[run-id]", "Run ID (defaults to latest)").option("-r, --repo <owner/repo>", "Filter by repository").action(async (_runId, _options) => {
605
+ try {
606
+ let config;
607
+ try {
608
+ config = readConfig();
609
+ } catch {
610
+ }
611
+ const run = getRun(_runId);
612
+ if (!run) {
613
+ console.log(pc4.yellow("No runs found. Run `codowave run <issue>` to start a new run."));
614
+ return;
615
+ }
616
+ if (_options?.repo && run.repo !== _options.repo) {
617
+ console.log(pc4.yellow("No run found for repository " + _options.repo));
618
+ return;
619
+ }
620
+ console.log(pc4.bold("\n=== Run Status ===\n"));
621
+ console.log(pc4.bold("ID: ") + run.id);
622
+ console.log(pc4.bold("Repo: ") + run.repo);
623
+ console.log(pc4.bold("Issue: ") + run.issue);
624
+ console.log(pc4.bold("Status: ") + formatStatus(run.status));
625
+ console.log(pc4.bold("Branch: ") + (run.branchName || pc4.gray("(none)")));
626
+ if (run.prNumber) {
627
+ console.log(pc4.bold("PR: ") + "#" + run.prNumber + " - " + (run.prTitle || ""));
628
+ }
629
+ if (run.startedAt) {
630
+ console.log(pc4.bold("Started: ") + new Date(run.startedAt).toLocaleString());
631
+ }
632
+ if (run.completedAt) {
633
+ console.log(pc4.bold("Duration: ") + formatDuration(run.startedAt, run.completedAt));
634
+ } else if (run.startedAt) {
635
+ console.log(pc4.bold("Duration: ") + pc4.blue("running... ") + formatDuration(run.startedAt));
636
+ }
637
+ if (run.errorMessage) {
638
+ console.log(pc4.bold("Error: ") + pc4.red(run.errorMessage));
639
+ }
640
+ console.log(pc4.bold("\n=== Stages ===\n"));
641
+ for (const stage of run.stages) {
642
+ const statusIcon = formatStageStatus(stage.status);
643
+ const statusText = pc4.bold("[" + stage.status + "]");
644
+ console.log(" " + statusIcon + " " + pc4.bold(stage.name.padEnd(20)) + " " + statusText);
645
+ }
646
+ console.log("");
647
+ } catch (err) {
648
+ const message = err instanceof Error ? err.message : String(err);
649
+ console.error(pc4.red("\n=== Error: " + message + " ===\n"));
650
+ process.exit(1);
703
651
  }
704
652
  });
705
653
 
706
654
  // src/commands/logs.ts
707
- var logs_exports = {};
708
- __export(logs_exports, {
709
- logsCommand: () => logsCommand
710
- });
711
655
  import { Command as Command4 } from "commander";
712
656
  import pc5 from "picocolors";
713
- var logsCommand;
714
- var init_logs = __esm({
715
- "src/commands/logs.ts"() {
716
- "use strict";
717
- init_config();
718
- init_status();
719
- logsCommand = new Command4("logs").description("Stream logs for a Codowave run").argument("[run-id]", "Run ID (defaults to latest)").option("-f, --follow", "Follow log output (SSE stream)").option("-s, --stage <name>", "Show logs for a specific stage").option("--no-color", "Disable colored output").action(async (_runId, _options) => {
720
- try {
721
- let config;
722
- try {
723
- config = readConfig();
724
- } catch {
725
- }
726
- const run = getRun(_runId);
727
- if (!run) {
728
- console.log(pc5.yellow("No runs found. Run `codowave run <issue>` to start a new run."));
729
- return;
730
- }
731
- if (_options?.stage) {
732
- const stage = run.stages.find((s) => s.name === _options.stage);
733
- if (!stage) {
734
- console.log(pc5.red('Stage "' + _options.stage + '" not found.'));
735
- console.log(pc5.gray("Available stages: ") + run.stages.map((s) => s.name).join(", "));
736
- return;
737
- }
738
- console.log(pc5.bold("\n=== Logs: " + stage.name + " ===\n"));
739
- console.log(pc5.bold("Status: ") + stage.status);
740
- if (stage.logs) {
741
- console.log(pc5.gray("\n--- Output ---\n"));
742
- console.log(stage.logs);
743
- } else {
744
- console.log(pc5.gray("\n(no logs available yet)"));
745
- }
746
- if (_options.follow && stage.status === "running") {
747
- console.log(pc5.blue("\n--- Following live logs (Ctrl+C to exit) ---\n"));
748
- console.log(pc5.gray("(Live streaming would connect to API SSE endpoint in production)"));
749
- }
750
- console.log("");
751
- return;
752
- }
753
- console.log(pc5.bold("\n=== Logs: " + run.id + " ===\n"));
754
- console.log(pc5.bold("Issue: ") + run.issue);
755
- console.log(pc5.bold("Status: ") + run.status);
756
- console.log("");
757
- for (const stage of run.stages) {
758
- const statusIcon = stage.status === "completed" ? "[+]" : stage.status === "failed" ? "[x]" : stage.status === "running" ? "[~]" : "[ ]";
759
- console.log(pc5.bold("\n" + statusIcon + " " + stage.name + "\n"));
760
- if (stage.logs) {
761
- console.log(stage.logs);
762
- } else if (stage.status === "pending") {
763
- console.log(pc5.gray("(pending)"));
764
- } else if (stage.status === "running") {
765
- console.log(pc5.blue("(running...)"));
766
- } else if (stage.status === "skipped") {
767
- console.log(pc5.gray("(skipped)"));
768
- }
769
- }
770
- if (_options?.follow && run.status === "in_progress") {
771
- console.log(pc5.blue("\n--- Following live logs (Ctrl+C to exit) ---\n"));
772
- console.log(pc5.gray("(Live streaming would connect to API SSE endpoint in production)"));
773
- let dots = 0;
774
- const interval = setInterval(() => {
775
- dots = (dots + 1) % 4;
776
- process.stdout.write(pc5.blue("\r" + " ".repeat(dots) + " waiting for updates..."));
777
- }, 500);
778
- process.on("SIGINT", () => {
779
- clearInterval(interval);
780
- console.log(pc5.gray("\n\n(Stopped following)"));
781
- process.exit(0);
782
- });
783
- }
784
- console.log("");
785
- } catch (err) {
786
- const message = err instanceof Error ? err.message : String(err);
787
- console.error(pc5.red("\n=== Error: " + message + " ===\n"));
788
- process.exit(1);
657
+ var logsCommand = new Command4("logs").description("Stream logs for a Codowave run").argument("[run-id]", "Run ID (defaults to latest)").option("-f, --follow", "Follow log output (SSE stream)").option("-s, --stage <name>", "Show logs for a specific stage").option("--no-color", "Disable colored output").action(async (_runId, _options) => {
658
+ try {
659
+ let config;
660
+ try {
661
+ config = readConfig();
662
+ } catch {
663
+ }
664
+ const run = getRun(_runId);
665
+ if (!run) {
666
+ console.log(pc5.yellow("No runs found. Run `codowave run <issue>` to start a new run."));
667
+ return;
668
+ }
669
+ if (_options?.stage) {
670
+ const stage = run.stages.find((s) => s.name === _options.stage);
671
+ if (!stage) {
672
+ console.log(pc5.red('Stage "' + _options.stage + '" not found.'));
673
+ console.log(pc5.gray("Available stages: ") + run.stages.map((s) => s.name).join(", "));
674
+ return;
675
+ }
676
+ console.log(pc5.bold("\n=== Logs: " + stage.name + " ===\n"));
677
+ console.log(pc5.bold("Status: ") + stage.status);
678
+ if (stage.logs) {
679
+ console.log(pc5.gray("\n--- Output ---\n"));
680
+ console.log(stage.logs);
681
+ } else {
682
+ console.log(pc5.gray("\n(no logs available yet)"));
683
+ }
684
+ if (_options.follow && stage.status === "running") {
685
+ console.log(pc5.blue("\n--- Following live logs (Ctrl+C to exit) ---\n"));
686
+ console.log(pc5.gray("(Live streaming would connect to API SSE endpoint in production)"));
687
+ }
688
+ console.log("");
689
+ return;
690
+ }
691
+ console.log(pc5.bold("\n=== Logs: " + run.id + " ===\n"));
692
+ console.log(pc5.bold("Issue: ") + run.issue);
693
+ console.log(pc5.bold("Status: ") + run.status);
694
+ console.log("");
695
+ for (const stage of run.stages) {
696
+ const statusIcon = stage.status === "completed" ? "[+]" : stage.status === "failed" ? "[x]" : stage.status === "running" ? "[~]" : "[ ]";
697
+ console.log(pc5.bold("\n" + statusIcon + " " + stage.name + "\n"));
698
+ if (stage.logs) {
699
+ console.log(stage.logs);
700
+ } else if (stage.status === "pending") {
701
+ console.log(pc5.gray("(pending)"));
702
+ } else if (stage.status === "running") {
703
+ console.log(pc5.blue("(running...)"));
704
+ } else if (stage.status === "skipped") {
705
+ console.log(pc5.gray("(skipped)"));
789
706
  }
790
- });
707
+ }
708
+ if (_options?.follow && run.status === "in_progress") {
709
+ console.log(pc5.blue("\n--- Following live logs (Ctrl+C to exit) ---\n"));
710
+ console.log(pc5.gray("(Live streaming would connect to API SSE endpoint in production)"));
711
+ let dots = 0;
712
+ const interval = setInterval(() => {
713
+ dots = (dots + 1) % 4;
714
+ process.stdout.write(pc5.blue("\r" + " ".repeat(dots) + " waiting for updates..."));
715
+ }, 500);
716
+ process.on("SIGINT", () => {
717
+ clearInterval(interval);
718
+ console.log(pc5.gray("\n\n(Stopped following)"));
719
+ process.exit(0);
720
+ });
721
+ }
722
+ console.log("");
723
+ } catch (err) {
724
+ const message = err instanceof Error ? err.message : String(err);
725
+ console.error(pc5.red("\n=== Error: " + message + " ===\n"));
726
+ process.exit(1);
791
727
  }
792
728
  });
793
729
 
794
730
  // src/commands/config-cmd.ts
795
- var config_cmd_exports = {};
796
- __export(config_cmd_exports, {
797
- configCommand: () => configCommand
798
- });
799
731
  import { Command as Command5 } from "commander";
800
732
  import pc6 from "picocolors";
801
- var configCommand;
802
- var init_config_cmd = __esm({
803
- "src/commands/config-cmd.ts"() {
804
- "use strict";
805
- init_config();
806
- configCommand = new Command5("config").description("Get or set Codowave configuration values");
807
- configCommand.command("list").description("List all available config options").action(() => {
808
- console.log(pc6.bold("\n\u{1F4CB} Available Config Options:\n"));
809
- console.log(` ${pc6.cyan("apiKey")} ${pc6.gray("\u2014 Your Codowave API key")}`);
810
- console.log(` ${pc6.cyan("apiUrl")} ${pc6.gray("\u2014 API endpoint URL (default: https://api.codowave.com)")}`);
811
- console.log(` ${pc6.cyan("repos")} ${pc6.gray("\u2014 List of configured repositories")}`);
812
- console.log(` ${pc6.cyan("configPath")} ${pc6.gray("\u2014 Path to the config file")}`);
813
- console.log("");
814
- });
815
- configCommand.command("get <key>").description("Get a config value").action((key) => {
816
- try {
817
- const config = readConfigOrThrow();
818
- if (key === "configPath") {
819
- console.log(pc6.green(getConfigPath()));
820
- return;
821
- }
822
- if (key === "repos") {
823
- if (config.repos.length === 0) {
824
- console.log(pc6.yellow("No repos configured."));
825
- } else {
826
- console.log(pc6.bold("\n\u{1F4E6} Configured Repositories:\n"));
827
- config.repos.forEach((repo, index) => {
828
- console.log(` ${index + 1}. ${pc6.cyan(`${repo.owner}/${repo.name}`)}`);
829
- if (repo.id) {
830
- console.log(` ${pc6.gray("ID: " + repo.id)}`);
831
- }
832
- });
833
- console.log("");
834
- }
835
- return;
836
- }
837
- const value = config[key];
838
- if (value === void 0) {
839
- console.error(pc6.red(`\u2716 Unknown config key: ${key}`));
840
- console.log(pc6.gray(` Run \`codowave config list\` to see available options.`));
841
- process.exit(1);
842
- }
843
- console.log(value);
844
- } catch (err) {
845
- console.error(pc6.red(`\u2716 ${err instanceof Error ? err.message : String(err)}`));
846
- process.exit(1);
847
- }
848
- });
849
- configCommand.command("set <key> <value>").description("Set a config value").action((key, value) => {
850
- try {
851
- const validKeys = ["apiKey", "apiUrl"];
852
- if (!validKeys.includes(key)) {
853
- console.error(pc6.red(`\u2716 Cannot set '${key}' directly.`));
854
- console.log(pc6.gray(` For 'repos', use \`codowave init\` to manage repositories.`));
855
- console.log(pc6.gray(` Run \`codowave config list\` to see available options.`));
856
- process.exit(1);
857
- }
858
- if (key === "apiUrl") {
859
- try {
860
- new URL(value);
861
- } catch {
862
- console.error(pc6.red(`\u2716 Invalid URL: ${value}`));
863
- process.exit(1);
733
+ var configCommand = new Command5("config").description("Get or set Codowave configuration values");
734
+ configCommand.command("list").description("List all available config options").action(() => {
735
+ console.log(pc6.bold("\n\u{1F4CB} Available Config Options:\n"));
736
+ console.log(` ${pc6.cyan("apiKey")} ${pc6.gray("\u2014 Your Codowave API key")}`);
737
+ console.log(` ${pc6.cyan("apiUrl")} ${pc6.gray("\u2014 API endpoint URL (default: https://api.codowave.com)")}`);
738
+ console.log(` ${pc6.cyan("repos")} ${pc6.gray("\u2014 List of configured repositories")}`);
739
+ console.log(` ${pc6.cyan("configPath")} ${pc6.gray("\u2014 Path to the config file")}`);
740
+ console.log("");
741
+ });
742
+ configCommand.command("get <key>").description("Get a config value").action((key) => {
743
+ try {
744
+ const config = readConfigOrThrow();
745
+ if (key === "configPath") {
746
+ console.log(pc6.green(getConfigPath()));
747
+ return;
748
+ }
749
+ if (key === "repos") {
750
+ if (config.repos.length === 0) {
751
+ console.log(pc6.yellow("No repos configured."));
752
+ } else {
753
+ console.log(pc6.bold("\n\u{1F4E6} Configured Repositories:\n"));
754
+ config.repos.forEach((repo, index) => {
755
+ console.log(` ${index + 1}. ${pc6.cyan(`${repo.owner}/${repo.name}`)}`);
756
+ if (repo.id) {
757
+ console.log(` ${pc6.gray("ID: " + repo.id)}`);
864
758
  }
865
- }
866
- const updates = { [key]: value };
867
- const newConfig = updateConfig(updates);
868
- console.log(pc6.green(`\u2713 Updated ${key}`));
869
- console.log(pc6.gray(` ${key} = ${newConfig[key]}`));
870
- } catch (err) {
871
- console.error(pc6.red(`\u2716 ${err instanceof Error ? err.message : String(err)}`));
872
- process.exit(1);
759
+ });
760
+ console.log("");
873
761
  }
874
- });
875
- configCommand.command("show").description("Show all current config values").action(() => {
762
+ return;
763
+ }
764
+ const value = config[key];
765
+ if (value === void 0) {
766
+ console.error(pc6.red(`\u2716 Unknown config key: ${key}`));
767
+ console.log(pc6.gray(` Run \`codowave config list\` to see available options.`));
768
+ process.exit(1);
769
+ }
770
+ console.log(value);
771
+ } catch (err) {
772
+ console.error(pc6.red(`\u2716 ${err instanceof Error ? err.message : String(err)}`));
773
+ process.exit(1);
774
+ }
775
+ });
776
+ configCommand.command("set <key> <value>").description("Set a config value").action((key, value) => {
777
+ try {
778
+ const validKeys = ["apiKey", "apiUrl"];
779
+ if (!validKeys.includes(key)) {
780
+ console.error(pc6.red(`\u2716 Cannot set '${key}' directly.`));
781
+ console.log(pc6.gray(` For 'repos', use \`codowave init\` to manage repositories.`));
782
+ console.log(pc6.gray(` Run \`codowave config list\` to see available options.`));
783
+ process.exit(1);
784
+ }
785
+ if (key === "apiUrl") {
876
786
  try {
877
- const config = readConfigOrThrow();
878
- console.log(pc6.bold("\n\u2699\uFE0F Current Configuration:\n"));
879
- console.log(` ${pc6.cyan("apiKey")}: ${config.apiKey ? pc6.green("\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022") + pc6.gray(" (hidden)") : pc6.yellow("not set")}`);
880
- console.log(` ${pc6.cyan("apiUrl")}: ${config.apiUrl}`);
881
- console.log(` ${pc6.cyan("repos")}: ${config.repos.length} repository(s) configured`);
882
- console.log(` ${pc6.cyan("configPath")}: ${pc6.gray(getConfigPath())}`);
883
- if (config.repos.length > 0) {
884
- console.log(pc6.bold(pc6.gray("\n Repositories:")));
885
- config.repos.forEach((repo) => {
886
- console.log(` \u2022 ${repo.owner}/${repo.name}${repo.id ? pc6.gray(` (${repo.id})`) : ""}`);
887
- });
888
- }
889
- console.log("");
890
- } catch (err) {
891
- console.error(pc6.red(`\u2716 ${err instanceof Error ? err.message : String(err)}`));
787
+ new URL(value);
788
+ } catch {
789
+ console.error(pc6.red(`\u2716 Invalid URL: ${value}`));
892
790
  process.exit(1);
893
791
  }
894
- });
895
- configCommand.action(() => {
896
- configCommand.help();
897
- });
792
+ }
793
+ const updates = { [key]: value };
794
+ const newConfig = updateConfig(updates);
795
+ console.log(pc6.green(`\u2713 Updated ${key}`));
796
+ console.log(pc6.gray(` ${key} = ${newConfig[key]}`));
797
+ } catch (err) {
798
+ console.error(pc6.red(`\u2716 ${err instanceof Error ? err.message : String(err)}`));
799
+ process.exit(1);
800
+ }
801
+ });
802
+ configCommand.command("show").description("Show all current config values").action(() => {
803
+ try {
804
+ const config = readConfigOrThrow();
805
+ console.log(pc6.bold("\n\u2699\uFE0F Current Configuration:\n"));
806
+ console.log(` ${pc6.cyan("apiKey")}: ${config.apiKey ? pc6.green("\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022") + pc6.gray(" (hidden)") : pc6.yellow("not set")}`);
807
+ console.log(` ${pc6.cyan("apiUrl")}: ${config.apiUrl}`);
808
+ console.log(` ${pc6.cyan("repos")}: ${config.repos.length} repository(s) configured`);
809
+ console.log(` ${pc6.cyan("configPath")}: ${pc6.gray(getConfigPath())}`);
810
+ if (config.repos.length > 0) {
811
+ console.log(pc6.bold(pc6.gray("\n Repositories:")));
812
+ config.repos.forEach((repo) => {
813
+ console.log(` \u2022 ${repo.owner}/${repo.name}${repo.id ? pc6.gray(` (${repo.id})`) : ""}`);
814
+ });
815
+ }
816
+ console.log("");
817
+ } catch (err) {
818
+ console.error(pc6.red(`\u2716 ${err instanceof Error ? err.message : String(err)}`));
819
+ process.exit(1);
898
820
  }
899
821
  });
822
+ configCommand.action(() => {
823
+ configCommand.help();
824
+ });
900
825
 
901
826
  // src/commands/connect.ts
902
- var connect_exports = {};
903
- __export(connect_exports, {
904
- connectCommand: () => connectCommand,
905
- performConnect: () => performConnect
906
- });
907
827
  import { Command as Command6 } from "commander";
908
828
  import pc7 from "picocolors";
909
- async function performConnect(accessToken) {
910
- const config = updateConfig({
911
- apiKey: accessToken,
912
- apiUrl: PRO_API_URL
913
- });
914
- console.log(pc7.green("\u2713 Connected to Codowave Pro!"));
915
- console.log(pc7.gray(` API URL: ${config.apiUrl}`));
916
- }
917
- var PRO_API_URL, connectCommand;
918
- var init_connect = __esm({
919
- "src/commands/connect.ts"() {
920
- "use strict";
921
- init_config();
922
- PRO_API_URL = "https://api.codowave.com";
923
- connectCommand = new Command6("connect").description("Connect to Codowave Pro (upgrade from OSS)").action(async () => {
924
- try {
925
- console.log(pc7.bold("\n\u{1F517} Codowave Connect\n"));
926
- console.log(pc7.gray("This command upgrades your OSS installation to Codowave Pro.\n"));
927
- const config = readConfig();
928
- const isAlreadyPro = config?.apiUrl === PRO_API_URL;
929
- if (isAlreadyPro) {
930
- console.log(pc7.green("\u2713 You are already connected to Codowave Pro!"));
931
- console.log(pc7.gray(` API URL: ${config?.apiUrl}`));
932
- console.log("");
933
- return;
934
- }
935
- console.log(pc7.blue("Starting OAuth device flow...\n"));
936
- console.log(pc7.gray(" 1. Requesting device code..."));
937
- const deviceCode = `CODOWAVE-${Date.now().toString(36).toUpperCase()}`;
938
- const verificationUri = "https://codowave.com/activate";
939
- console.log(pc7.green("\n \u26A0\uFE0F Device Code: ") + pc7.bold(deviceCode));
940
- console.log(pc7.gray("\n 2. Please visit: ") + pc7.cyan(verificationUri));
941
- console.log(pc7.gray(" and enter the device code above.\n"));
942
- console.log(pc7.yellow(" \u2139\uFE0F This is a stub implementation."));
943
- console.log(pc7.gray(" In production, this would poll for OAuth completion.\n"));
944
- console.log(pc7.blue(" 3. Would save Pro token and switch API URL...\n"));
945
- console.log(pc7.bold("What would happen:\n"));
946
- console.log(` \u2022 Save Pro API token to ${getConfigPath()}`);
947
- console.log(` \u2022 Set apiUrl to ${PRO_API_URL}`);
948
- console.log("");
949
- console.log(pc7.gray("Run with ") + pc7.cyan("CODOWAVE_CONNECT=1") + pc7.gray(" to enable (not implemented yet)"));
950
- console.log("");
951
- } catch (err) {
952
- const message = err instanceof Error ? err.message : String(err);
953
- console.error(pc7.red(`
829
+ var PRO_API_URL = "https://api.codowave.com";
830
+ var connectCommand = new Command6("connect").description("Connect to Codowave Pro (upgrade from OSS)").action(async () => {
831
+ try {
832
+ console.log(pc7.bold("\n\u{1F517} Codowave Connect\n"));
833
+ console.log(pc7.gray("This command upgrades your OSS installation to Codowave Pro.\n"));
834
+ const config = readConfig();
835
+ const isAlreadyPro = config?.apiUrl === PRO_API_URL;
836
+ if (isAlreadyPro) {
837
+ console.log(pc7.green("\u2713 You are already connected to Codowave Pro!"));
838
+ console.log(pc7.gray(` API URL: ${config?.apiUrl}`));
839
+ console.log("");
840
+ return;
841
+ }
842
+ console.log(pc7.blue("Starting OAuth device flow...\n"));
843
+ console.log(pc7.gray(" 1. Requesting device code..."));
844
+ const deviceCode = `CODOWAVE-${Date.now().toString(36).toUpperCase()}`;
845
+ const verificationUri = "https://codowave.com/activate";
846
+ console.log(pc7.green("\n \u26A0\uFE0F Device Code: ") + pc7.bold(deviceCode));
847
+ console.log(pc7.gray("\n 2. Please visit: ") + pc7.cyan(verificationUri));
848
+ console.log(pc7.gray(" and enter the device code above.\n"));
849
+ console.log(pc7.yellow(" \u2139\uFE0F This is a stub implementation."));
850
+ console.log(pc7.gray(" In production, this would poll for OAuth completion.\n"));
851
+ console.log(pc7.blue(" 3. Would save Pro token and switch API URL...\n"));
852
+ console.log(pc7.bold("What would happen:\n"));
853
+ console.log(` \u2022 Save Pro API token to ${getConfigPath()}`);
854
+ console.log(` \u2022 Set apiUrl to ${PRO_API_URL}`);
855
+ console.log("");
856
+ console.log(pc7.gray("Run with ") + pc7.cyan("CODOWAVE_CONNECT=1") + pc7.gray(" to enable (not implemented yet)"));
857
+ console.log("");
858
+ } catch (err) {
859
+ const message = err instanceof Error ? err.message : String(err);
860
+ console.error(pc7.red(`
954
861
  \u2716 Error: ${message}
955
862
  `));
956
- process.exit(1);
957
- }
958
- });
863
+ process.exit(1);
959
864
  }
960
865
  });
961
866
 
962
867
  // src/index.ts
963
- init_config();
964
- import { Command as Command7 } from "commander";
965
868
  import { createRequire } from "module";
966
869
  var require2 = createRequire(import.meta.url);
967
870
  var { version } = require2("../package.json");
968
871
  var VERSION = version;
969
872
  var program = new Command7();
970
873
  program.name("codowave").description("Codowave OSS CLI \u2014 AI-powered coding agent for your GitHub repositories").version(VERSION, "-v, --version", "Output the current version").option("--api-url <url>", "Override the Codowave API URL");
971
- var { initCommand: initCommand2 } = await Promise.resolve().then(() => (init_init(), init_exports));
972
- var { runCommand: runCommand2 } = await Promise.resolve().then(() => (init_run(), run_exports));
973
- var { statusCommand: statusCommand2 } = await Promise.resolve().then(() => (init_status(), status_exports));
974
- var { logsCommand: logsCommand2 } = await Promise.resolve().then(() => (init_logs(), logs_exports));
975
- var { configCommand: configCommand2 } = await Promise.resolve().then(() => (init_config_cmd(), config_cmd_exports));
976
- var { connectCommand: connectCommand2 } = await Promise.resolve().then(() => (init_connect(), connect_exports));
977
- program.addCommand(initCommand2);
978
- program.addCommand(runCommand2);
979
- program.addCommand(statusCommand2);
980
- program.addCommand(logsCommand2);
981
- program.addCommand(configCommand2);
982
- program.addCommand(connectCommand2);
874
+ program.addCommand(initCommand);
875
+ program.addCommand(runCommand);
876
+ program.addCommand(statusCommand);
877
+ program.addCommand(logsCommand);
878
+ program.addCommand(configCommand);
879
+ program.addCommand(connectCommand);
983
880
  var args = process.argv.slice(2);
984
881
  var isInitOrHelp = args[0] === "init" || args.includes("--help") || args.includes("-h") || args.includes("--version") || args.includes("-v") || args.length === 0;
985
882
  if (!isInitOrHelp) {
986
- const config = await readConfig();
883
+ const config = readConfig();
987
884
  if (!config?.apiUrl) {
988
885
  console.log("\n\u274C Codowave not initialized. Run: codowave init\n");
989
886
  process.exit(1);