codowave 0.1.7 → 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/cli.js ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import('./index.js')
package/dist/index.d.ts CHANGED
@@ -1 +1,2 @@
1
- #!/usr/bin/env node
1
+
2
+ export { }
package/dist/index.js ADDED
@@ -0,0 +1,890 @@
1
+ // src/index.ts
2
+ import { Command as Command7 } from "commander";
3
+
4
+ // src/config.ts
5
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
6
+ import { join } from "path";
7
+ import { homedir } from "os";
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");
29
+ function readConfig() {
30
+ if (!existsSync(CONFIG_FILE)) {
31
+ return null;
32
+ }
33
+ try {
34
+ const raw = readFileSync(CONFIG_FILE, "utf-8");
35
+ const json = JSON.parse(raw);
36
+ const parsed = ConfigSchema.safeParse(json);
37
+ if (!parsed.success) {
38
+ return null;
39
+ }
40
+ return parsed.data;
41
+ } catch (err) {
42
+ console.warn(`[config] Failed to parse ${CONFIG_FILE}:`, err);
43
+ return null;
44
+ }
45
+ }
46
+ function readConfigOrThrow() {
47
+ const config = readConfig();
48
+ if (!config) {
49
+ throw new Error(
50
+ `No Codowave config found. Run \`codowave init\` to get started.`
51
+ );
52
+ }
53
+ return config;
54
+ }
55
+ function writeConfig(config) {
56
+ if (!existsSync(CONFIG_DIR)) {
57
+ mkdirSync(CONFIG_DIR, { recursive: true });
58
+ }
59
+ writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + "\n", "utf-8");
60
+ }
61
+ function updateConfig(updates) {
62
+ const current = readConfig() ?? {
63
+ apiKey: "",
64
+ apiUrl: "https://api.codowave.com",
65
+ repos: []
66
+ };
67
+ const merged = {
68
+ ...current,
69
+ ...updates
70
+ };
71
+ writeConfig(merged);
72
+ return merged;
73
+ }
74
+ function getConfigPath() {
75
+ return CONFIG_FILE;
76
+ }
77
+
78
+ // src/commands/init.tsx
79
+ import { Command } from "commander";
80
+ import pc2 from "picocolors";
81
+ import { render } from "ink";
82
+
83
+ // src/components/init/GithubAppStep.tsx
84
+ import { useState, useEffect } from "react";
85
+ import {
86
+ Box,
87
+ Text,
88
+ useInput
89
+ } from "ink";
90
+ import Spinner from "ink-spinner";
91
+ import pc from "picocolors";
92
+ import { jsx, jsxs } from "react/jsx-runtime";
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"
114
+ }
115
+ });
116
+ if (!response.ok) {
117
+ if (response.status === 401) {
118
+ throw new Error("Invalid API key. Please check and try again.");
119
+ }
120
+ throw new Error(`Failed to fetch repositories: ${response.status}`);
121
+ }
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);
129
+ }
130
+ setSelectedRepos(allIndices);
131
+ }
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;
159
+ }
160
+ if (key.escape) {
161
+ onCancel();
162
+ return;
163
+ }
164
+ if (key.backspace || input === "\b") {
165
+ setApiKey((prev) => prev.slice(0, -1));
166
+ setError(null);
167
+ return;
168
+ }
169
+ if (input && !key.ctrl && !key.meta) {
170
+ setApiKey((prev) => prev + input);
171
+ setError(null);
172
+ return;
173
+ }
174
+ } else if (step === "repos") {
175
+ if (key.escape) {
176
+ handleGoBack();
177
+ return;
178
+ }
179
+ if (key.return) {
180
+ handleConfirm();
181
+ return;
182
+ }
183
+ if (input === " ") {
184
+ toggleRepo(currentSelection);
185
+ return;
186
+ }
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());
205
+ return;
206
+ }
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
+ {
306
+ apiUrl,
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(`
329
+ Config saved to: ${pc2.cyan(getConfigPath())}`);
330
+ console.log(` API URL: ${pc2.cyan(apiUrl)}`);
331
+ console.log(` Repositories: ${pc2.bold(capturedRepos.length)} configured
332
+ `);
333
+ console.log(pc2.gray(" Run ") + pc2.bold("codowave run") + pc2.gray(" to start coding!\n"));
334
+ });
335
+
336
+ // src/commands/run.ts
337
+ import { Command as Command2 } from "commander";
338
+ import pc3 from "picocolors";
339
+ var demoRuns = /* @__PURE__ */ new Map();
340
+ function parseIssue(input) {
341
+ const urlMatch = input.match(/github\.com\/([^/]+)\/([^/]+)\/issues\/(\d+)/);
342
+ if (urlMatch && urlMatch[1] && urlMatch[2] && urlMatch[3]) {
343
+ return { owner: urlMatch[1], repo: urlMatch[2], number: parseInt(urlMatch[3], 10) };
344
+ }
345
+ const repoMatch = input.match(/([^/]+)\/([^#]+)#(\d+)/);
346
+ if (repoMatch && repoMatch[1] && repoMatch[2] && repoMatch[3]) {
347
+ return { owner: repoMatch[1], repo: repoMatch[2], number: parseInt(repoMatch[3], 10) };
348
+ }
349
+ const numMatch = input.match(/^(\d+)$/);
350
+ if (numMatch && numMatch[1]) {
351
+ return { owner: "", repo: "", number: parseInt(numMatch[1], 10) };
352
+ }
353
+ return null;
354
+ }
355
+ async function triggerRun(config, issue) {
356
+ const apiUrl = config.apiUrl;
357
+ const apiKey = config.apiKey;
358
+ const repoConfig = config.repos.find(
359
+ (r) => r.owner === issue.owner && r.name === issue.repo
360
+ );
361
+ if (!repoConfig) {
362
+ throw new Error(
363
+ `Repository ${issue.owner}/${issue.repo} not configured. Run \`codowave config add-repo ${issue.owner}/${issue.repo}\``
364
+ );
365
+ }
366
+ const response = await fetch(`${apiUrl}/api/runs`, {
367
+ method: "POST",
368
+ headers: {
369
+ "Content-Type": "application/json",
370
+ Authorization: `Bearer ${apiKey}`
371
+ },
372
+ body: JSON.stringify({
373
+ repositoryId: repoConfig.id,
374
+ issueNumber: issue.number
375
+ })
376
+ });
377
+ if (!response.ok) {
378
+ const error = await response.text();
379
+ throw new Error(`Failed to trigger run: ${response.status} ${error}`);
380
+ }
381
+ const data = await response.json();
382
+ return data.runId;
383
+ }
384
+ function createDemoRun(issue) {
385
+ const runId = `run-${Date.now()}`;
386
+ const run = {
387
+ id: runId,
388
+ repo: issue.owner && issue.repo ? `${issue.owner}/${issue.repo}` : "CodowaveAI/Codowave",
389
+ status: "in_progress",
390
+ issue: `#${issue.number}`,
391
+ branchName: `agent/issue-${issue.number}`,
392
+ startedAt: (/* @__PURE__ */ new Date()).toISOString(),
393
+ stages: [
394
+ { name: "context", status: "pending" },
395
+ { name: "planning", status: "pending" },
396
+ { name: "implementation", status: "pending" },
397
+ { name: "testing", status: "pending" },
398
+ { name: "pr-creation", status: "pending" }
399
+ ]
400
+ };
401
+ demoRuns.set(runId, run);
402
+ return run;
403
+ }
404
+ function streamDemoRun(run) {
405
+ const stages = ["context", "planning", "implementation", "testing", "pr-creation"];
406
+ let currentStage = 0;
407
+ console.log(pc3.bold("\n=== Starting Run ===\n"));
408
+ console.log(pc3.bold("Run ID: ") + run.id);
409
+ console.log(pc3.bold("Repo: ") + run.repo);
410
+ console.log(pc3.bold("Issue: ") + run.issue);
411
+ console.log(pc3.bold("Branch: ") + run.branchName);
412
+ console.log("");
413
+ const interval = setInterval(() => {
414
+ if (currentStage >= stages.length) {
415
+ clearInterval(interval);
416
+ run.status = "completed";
417
+ run.completedAt = (/* @__PURE__ */ new Date()).toISOString();
418
+ run.prNumber = 100 + Math.floor(Math.random() * 50);
419
+ run.prTitle = `feat: Implement issue #${run.issue}`;
420
+ console.log(pc3.green("\n\u2713 Run completed successfully!"));
421
+ console.log(pc3.bold("\n=== Result ===\n"));
422
+ console.log(pc3.bold("PR: ") + `#${run.prNumber} - ${run.prTitle}`);
423
+ console.log(pc3.bold("Branch: ") + run.branchName);
424
+ console.log("");
425
+ process.exit(0);
426
+ return;
427
+ }
428
+ const stageName = stages[currentStage];
429
+ const stage = run.stages.find((s) => s.name === stageName);
430
+ if (stage) {
431
+ stage.status = "running";
432
+ console.log(pc3.blue(`
433
+ --- ${stageName} ---`));
434
+ setTimeout(() => {
435
+ stage.status = "completed";
436
+ stage.logs = `${stageName} completed successfully`;
437
+ currentStage++;
438
+ }, 1e3 + Math.random() * 2e3);
439
+ } else {
440
+ currentStage++;
441
+ }
442
+ }, 500);
443
+ process.on("SIGINT", () => {
444
+ clearInterval(interval);
445
+ run.status = "cancelled";
446
+ console.log(pc3.yellow("\n\n\u26A0 Run cancelled"));
447
+ process.exit(1);
448
+ });
449
+ }
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(`
484
+ Run started. Use \`codowave status ${runId}\` to check progress.`));
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(`
494
+ Use \`codowave status ${run.id}\` to check progress.`));
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(`
501
+ \u2716 Error: ${message}
502
+ `));
503
+ process.exit(1);
504
+ }
505
+ });
506
+
507
+ // src/commands/status.ts
508
+ import { Command as Command3 } from "commander";
509
+ import pc4 from "picocolors";
510
+ var demoRuns2 = /* @__PURE__ */ new Map();
511
+ function initDemoData() {
512
+ if (demoRuns2.size === 0) {
513
+ const demoRun = {
514
+ id: "latest",
515
+ repo: "CodowaveAI/Codowave",
516
+ status: "in_progress",
517
+ issue: "#53: Implement CLI status and logs commands",
518
+ branchName: "agent/issue-53",
519
+ startedAt: new Date(Date.now() - 5 * 60 * 1e3).toISOString(),
520
+ stages: [
521
+ { name: "context", status: "completed", logs: "Loaded 12 files, 3 PRs context" },
522
+ { name: "planning", status: "completed", logs: "Generated implementation plan" },
523
+ { name: "implementation", status: "running", logs: "Implementing status command..." },
524
+ { name: "testing", status: "pending" },
525
+ { name: "pr-creation", status: "pending" }
526
+ ]
527
+ };
528
+ demoRuns2.set(demoRun.id, demoRun);
529
+ const completedRun = {
530
+ id: "abc-123-def",
531
+ repo: "CodowaveAI/Codowave",
532
+ status: "completed",
533
+ issue: "#52: Add authentication flow",
534
+ prNumber: 78,
535
+ prTitle: "feat: Add OAuth authentication flow",
536
+ branchName: "feat/auth-flow",
537
+ startedAt: new Date(Date.now() - 60 * 60 * 1e3).toISOString(),
538
+ completedAt: new Date(Date.now() - 45 * 60 * 1e3).toISOString(),
539
+ stages: [
540
+ { name: "context", status: "completed" },
541
+ { name: "planning", status: "completed" },
542
+ { name: "implementation", status: "completed" },
543
+ { name: "testing", status: "completed" },
544
+ { name: "pr-creation", status: "completed" }
545
+ ]
546
+ };
547
+ demoRuns2.set(completedRun.id, completedRun);
548
+ }
549
+ }
550
+ function getRun(runId) {
551
+ initDemoData();
552
+ if (!runId) {
553
+ return Array.from(demoRuns2.values()).sort(
554
+ (a, b) => new Date(b.startedAt || 0).getTime() - new Date(a.startedAt || 0).getTime()
555
+ )[0];
556
+ }
557
+ return demoRuns2.get(runId);
558
+ }
559
+ function formatStatus(status) {
560
+ switch (status) {
561
+ case "pending":
562
+ return pc4.gray("pending");
563
+ case "in_progress":
564
+ return pc4.blue("in_progress");
565
+ case "completed":
566
+ return pc4.green("completed");
567
+ case "failed":
568
+ return pc4.red("failed");
569
+ case "cancelled":
570
+ return pc4.gray("cancelled");
571
+ default:
572
+ return pc4.gray(status);
573
+ }
574
+ }
575
+ function formatStageStatus(status) {
576
+ switch (status) {
577
+ case "pending":
578
+ return pc4.gray("[ ]");
579
+ case "running":
580
+ return pc4.blue("[~]");
581
+ case "completed":
582
+ return pc4.green("[+]");
583
+ case "failed":
584
+ return pc4.red("[x]");
585
+ case "skipped":
586
+ return pc4.gray("[-]");
587
+ default:
588
+ return pc4.gray("[?]");
589
+ }
590
+ }
591
+ function formatDuration(startedAt, completedAt) {
592
+ if (!startedAt) return "";
593
+ const start = new Date(startedAt).getTime();
594
+ const end = completedAt ? new Date(completedAt).getTime() : Date.now();
595
+ const seconds = Math.floor((end - start) / 1e3);
596
+ if (seconds < 60) return `${seconds}s`;
597
+ const minutes = Math.floor(seconds / 60);
598
+ const remainingSeconds = seconds % 60;
599
+ if (minutes < 60) return `${minutes}m ${remainingSeconds}s`;
600
+ const hours = Math.floor(minutes / 60);
601
+ const remainingMinutes = minutes % 60;
602
+ return `${hours}h ${remainingMinutes}m`;
603
+ }
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);
651
+ }
652
+ });
653
+
654
+ // src/commands/logs.ts
655
+ import { Command as Command4 } from "commander";
656
+ import pc5 from "picocolors";
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)"));
706
+ }
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);
727
+ }
728
+ });
729
+
730
+ // src/commands/config-cmd.ts
731
+ import { Command as Command5 } from "commander";
732
+ import pc6 from "picocolors";
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)}`);
758
+ }
759
+ });
760
+ console.log("");
761
+ }
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") {
786
+ try {
787
+ new URL(value);
788
+ } catch {
789
+ console.error(pc6.red(`\u2716 Invalid URL: ${value}`));
790
+ process.exit(1);
791
+ }
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);
820
+ }
821
+ });
822
+ configCommand.action(() => {
823
+ configCommand.help();
824
+ });
825
+
826
+ // src/commands/connect.ts
827
+ import { Command as Command6 } from "commander";
828
+ import pc7 from "picocolors";
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(`
861
+ \u2716 Error: ${message}
862
+ `));
863
+ process.exit(1);
864
+ }
865
+ });
866
+
867
+ // src/index.ts
868
+ import { createRequire } from "module";
869
+ var require2 = createRequire(import.meta.url);
870
+ var { version } = require2("../package.json");
871
+ var VERSION = version;
872
+ var program = new Command7();
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");
874
+ program.addCommand(initCommand);
875
+ program.addCommand(runCommand);
876
+ program.addCommand(statusCommand);
877
+ program.addCommand(logsCommand);
878
+ program.addCommand(configCommand);
879
+ program.addCommand(connectCommand);
880
+ var args = process.argv.slice(2);
881
+ var isInitOrHelp = args[0] === "init" || args.includes("--help") || args.includes("-h") || args.includes("--version") || args.includes("-v") || args.length === 0;
882
+ if (!isInitOrHelp) {
883
+ const config = readConfig();
884
+ if (!config?.apiUrl) {
885
+ console.log("\n\u274C Codowave not initialized. Run: codowave init\n");
886
+ process.exit(1);
887
+ }
888
+ }
889
+ program.parse();
890
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/config.ts","../src/commands/init.tsx","../src/components/init/GithubAppStep.tsx","../src/commands/run.ts","../src/commands/status.ts","../src/commands/logs.ts","../src/commands/config-cmd.ts","../src/commands/connect.ts"],"sourcesContent":["import { Command } from 'commander'\nimport { readConfig } from './config'\nimport { initCommand } from './commands/init.js'\nimport { runCommand } from './commands/run.js'\nimport { statusCommand } from './commands/status.js'\nimport { logsCommand } from './commands/logs.js'\nimport { configCommand } from './commands/config-cmd.js'\nimport { connectCommand } from './commands/connect.js'\n\n// Read version from package.json\nimport { createRequire } from 'module'\nconst require = createRequire(import.meta.url)\nconst { version } = require('../package.json')\n\nconst VERSION = version\n\nconst program = new Command()\n\nprogram\n .name('codowave')\n .description('Codowave OSS CLI — AI-powered coding agent for your GitHub repositories')\n .version(VERSION, '-v, --version', 'Output the current version')\n .option('--api-url <url>', 'Override the Codowave API URL')\n\nprogram.addCommand(initCommand)\nprogram.addCommand(runCommand)\nprogram.addCommand(statusCommand)\nprogram.addCommand(logsCommand)\nprogram.addCommand(configCommand)\nprogram.addCommand(connectCommand)\n\nconst args = process.argv.slice(2)\nconst isInitOrHelp = args[0] === 'init' || args.includes('--help') || args.includes('-h') || args.includes('--version') || args.includes('-v') || args.length === 0\n\nif (!isInitOrHelp) {\n const config = readConfig()\n if (!config?.apiUrl) {\n console.log('\\n❌ Codowave not initialized. Run: codowave init\\n')\n process.exit(1)\n }\n}\n\nprogram.parse()\n","import { readFileSync, writeFileSync, mkdirSync, existsSync } from \"fs\";\nimport { join } from \"path\";\nimport { homedir } from \"os\";\nimport { z } from \"zod\";\n\n// ── Schema ─────────────────────────────────────────────────────────────────\n\nexport const AIProviderSchema = z.object({\n provider: z.enum([\"openai\", \"anthropic\", \"minimax\", \"ollama\", \"custom\"]),\n apiKey: z.string().min(1),\n model: z.string().default(\"\"),\n baseUrl: z.string().url().optional(),\n});\n\nexport type AIProvider = z.infer<typeof AIProviderSchema>;\n\nexport const ConfigSchema = z.object({\n apiKey: z.string().min(1),\n apiUrl: z.string().url().default(\"https://api.codowave.com\"),\n repos: z\n .array(\n z.object({\n owner: z.string(),\n name: z.string(),\n id: z.string().optional(),\n })\n )\n .default([]),\n ai: AIProviderSchema.optional(),\n});\n\nexport type CodowaveConfig = z.infer<typeof ConfigSchema>;\n\n// ── Paths ──────────────────────────────────────────────────────────────────\n\nconst CONFIG_DIR = join(homedir(), \".codowave\");\nconst CONFIG_FILE = join(CONFIG_DIR, \"config.json\");\n\n// ── Read ───────────────────────────────────────────────────────────────────\n\nexport function readConfig(): CodowaveConfig | null {\n if (!existsSync(CONFIG_FILE)) {\n return null;\n }\n\n try {\n const raw = readFileSync(CONFIG_FILE, \"utf-8\");\n const json = JSON.parse(raw);\n const parsed = ConfigSchema.safeParse(json);\n\n if (!parsed.success) {\n return null;\n }\n\n return parsed.data;\n } catch (err) {\n console.warn(`[config] Failed to parse ${CONFIG_FILE}:`, err);\n return null;\n }\n}\n\nexport function readConfigOrThrow(): CodowaveConfig {\n const config = readConfig();\n if (!config) {\n throw new Error(\n `No Codowave config found. Run \\`codowave init\\` to get started.`\n );\n }\n return config;\n}\n\n// ── Write ──────────────────────────────────────────────────────────────────\n\nexport function writeConfig(config: CodowaveConfig): void {\n if (!existsSync(CONFIG_DIR)) {\n mkdirSync(CONFIG_DIR, { recursive: true });\n }\n\n writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + \"\\n\", \"utf-8\");\n}\n\nexport function updateConfig(\n updates: Partial<CodowaveConfig>\n): CodowaveConfig {\n const current = readConfig() ?? {\n apiKey: \"\",\n apiUrl: \"https://api.codowave.com\",\n repos: [],\n };\n\n const merged: CodowaveConfig = {\n ...current,\n ...updates,\n };\n\n writeConfig(merged);\n return merged;\n}\n\n// ── Config path getter (for display) ──────────────────────────────────────\n\nexport function getConfigPath(): string {\n return CONFIG_FILE;\n}\n","import { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { render } from \"ink\";\nimport React from \"react\";\nimport { writeConfig, readConfig, getConfigPath } from \"../config.js\";\nimport { GithubAppStep } from \"../components/init/GithubAppStep.js\";\n\ntype Repo = {\n\towner: string;\n\tname: string;\n\tid?: string;\n};\n\nexport const initCommand = new Command(\"init\")\n\t.description(\"Initialize Codowave and connect your GitHub repositories\")\n\t.action(async () => {\n\t\tconst existingConfig = readConfig();\n\t\tconst defaultApiUrl = \"https://api.codowave.com\";\n\t\tconst apiUrl = existingConfig?.apiUrl || defaultApiUrl;\n\n\t\t// If already initialized, ask if they want to reconfigure\n\t\tif (existingConfig?.apiKey) {\n\t\t\tconsole.log(pc.yellow(\"\\n⚠ Codowave is already initialized.\\n\"));\n\t\t\tconsole.log(` API URL: ${pc.cyan(existingConfig.apiUrl)}`);\n\t\t\tconsole.log(` Config: ${getConfigPath()}`);\n\t\t\tconsole.log(pc.gray(\"\\n Run this command again to reconfigure.\\n\"));\n\t\t\treturn;\n\t\t}\n\n\t\tlet wizardComplete = false;\n\t\tlet capturedApiKey = \"\";\n\t\tlet capturedRepos: Repo[] = [];\n\n\t\tconst { waitUntilExit } = render(\n\t\t\t<GithubAppStep\n\t\t\t\tapiUrl={apiUrl}\n\t\t\t\tonComplete={(apiKey, repos) => {\n\t\t\t\t\tcapturedApiKey = apiKey;\n\t\t\t\t\tcapturedRepos = repos;\n\t\t\t\t\twizardComplete = true;\n\t\t\t\t}}\n\t\t\t\tonCancel={() => {\n\t\t\t\t\tprocess.exit(0);\n\t\t\t\t}}\n\t\t\t/>\n\t\t);\n\n\t\tawait waitUntilExit();\n\n\t\tif (!wizardComplete) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Save the configuration\n\t\twriteConfig({\n\t\t\tapiKey: capturedApiKey,\n\t\t\tapiUrl: apiUrl,\n\t\t\trepos: capturedRepos,\n\t\t});\n\n\t\tconsole.log(pc.green(\"\\n✓ Initialization complete!\"));\n\t\tconsole.log(`\\n Config saved to: ${pc.cyan(getConfigPath())}`);\n\t\tconsole.log(` API URL: ${pc.cyan(apiUrl)}`);\n\t\tconsole.log(` Repositories: ${pc.bold(capturedRepos.length)} configured\\n`);\n\t\tconsole.log(pc.gray(\" Run \") + pc.bold(\"codowave run\") + pc.gray(\" to start coding!\\n\"));\n\t});\n","import React, { useState, useEffect, useRef } from \"react\";\nimport {\n Box,\n Text,\n useInput,\n} from \"ink\";\nimport Spinner from \"ink-spinner\";\nimport pc from \"picocolors\";\n\ntype Repo = {\n\towner: string;\n\tname: string;\n\tid?: string;\n};\n\ntype Props = {\n\tapiUrl: string;\n\tonComplete: (apiKey: string, repos: Repo[]) => void;\n\tonCancel: () => void;\n};\n\ntype Step = \"api-key\" | \"repos\";\n\nexport const GithubAppStep: React.FC<Props> = ({ apiUrl, onComplete, onCancel }) => {\n\tconst [step, setStep] = useState<Step>(\"api-key\");\n\tconst [apiKey, setApiKey] = useState(\"\");\n\tconst [repos, setRepos] = useState<Repo[]>([]);\n\tconst [selectedRepos, setSelectedRepos] = useState<Set<number>>(new Set());\n\tconst [currentSelection, setCurrentSelection] = useState(0);\n\tconst [loading, setLoading] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\n\t// Fetch repos when API key is validated\n\tuseEffect(() => {\n\t\tif (step === \"repos\" && apiKey && repos.length === 0 && !loading) {\n\t\t\tfetchRepos();\n\t\t}\n\t}, [step, apiKey]);\n\n\tasync function fetchRepos() {\n\t\tsetLoading(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\t// Call the API to get repositories\n\t\t\t// This endpoint should return the repos associated with the API key\n\t\t\tconst response = await fetch(`${apiUrl}/api/v1/repos`, {\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${apiKey}`,\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tif (response.status === 401) {\n\t\t\t\t\tthrow new Error(\"Invalid API key. Please check and try again.\");\n\t\t\t\t}\n\t\t\t\tthrow new Error(`Failed to fetch repositories: ${response.status}`);\n\t\t\t}\n\n\t\t\tconst data = await response.json() as { repos?: Repo[]; repositories?: Repo[] };\n\t\t\t// Expected response format: { repos: [{ owner, name, id? }] }\n\t\t\tconst fetchedRepos = data.repos || data.repositories || [];\n\t\t\tsetRepos(fetchedRepos);\n\t\t\t// Select all by default\n\t\t\tif (fetchedRepos.length > 0) {\n\t\t\t\tconst allIndices = new Set<number>();\n\t\t\t\tfor (let i = 0; i < fetchedRepos.length; i++) {\n\t\t\t\t\tallIndices.add(i);\n\t\t\t\t}\n\t\t\t\tsetSelectedRepos(allIndices);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tsetError(err instanceof Error ? err.message : \"Failed to fetch repositories\");\n\t\t} finally {\n\t\t\tsetLoading(false);\n\t\t}\n\t}\n\n\tfunction handleApiKeySubmit() {\n\t\tif (!apiKey.trim()) {\n\t\t\tsetError(\"API key cannot be empty\");\n\t\t\treturn;\n\t\t}\n\t\tsetError(null);\n\t\tsetStep(\"repos\");\n\t}\n\n\tfunction handleConfirm() {\n\t\tconst selected = Array.from(selectedRepos)\n\t\t\t.map((i) => repos[i])\n\t\t\t.filter((repo): repo is Repo => repo !== undefined);\n\t\tonComplete(apiKey, selected);\n\t}\n\n\tfunction handleGoBack() {\n\t\tsetStep(\"api-key\");\n\t\tsetError(null);\n\t}\n\n\t// Handle keyboard input\n\tuseInput((input, key) => {\n\t\tif (step === \"api-key\") {\n\t\t\t// Handle Enter key\n\t\t\tif (key.return) {\n\t\t\t\thandleApiKeySubmit();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Handle Escape key\n\t\t\tif (key.escape) {\n\t\t\t\tonCancel();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Handle backspace\n\t\t\tif (key.backspace || input === \"\\b\") {\n\t\t\t\tsetApiKey((prev) => prev.slice(0, -1));\n\t\t\t\tsetError(null);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Handle regular character input\n\t\t\tif (input && !key.ctrl && !key.meta) {\n\t\t\t\tsetApiKey((prev) => prev + input);\n\t\t\t\tsetError(null);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else if (step === \"repos\") {\n\t\t\t// Handle Escape key - go back\n\t\t\tif (key.escape) {\n\t\t\t\thandleGoBack();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Handle Enter key - confirm\n\t\t\tif (key.return) {\n\t\t\t\thandleConfirm();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Handle Space - toggle selection\n\t\t\tif (input === \" \") {\n\t\t\t\ttoggleRepo(currentSelection);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Handle Up arrow - move selection up\n\t\t\tif (key.upArrow) {\n\t\t\t\tsetCurrentSelection((prev) => Math.max(0, prev - 1));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Handle Down arrow - move selection down\n\t\t\tif (key.downArrow) {\n\t\t\t\tsetCurrentSelection((prev) => Math.min(repos.length - 1, prev + 1));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Handle 'a' key - select all\n\t\t\tif (input === \"a\" || input === \"A\") {\n\t\t\t\tconst allIndices = new Set<number>();\n\t\t\t\tfor (let i = 0; i < repos.length; i++) {\n\t\t\t\t\tallIndices.add(i);\n\t\t\t\t}\n\t\t\t\tsetSelectedRepos(allIndices);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Handle 'n' key - select none\n\t\t\tif (input === \"n\" || input === \"N\") {\n\t\t\t\tsetSelectedRepos(new Set());\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t});\n\n\tfunction toggleRepo(index: number) {\n\t\tconst newSelected = new Set(selectedRepos);\n\t\tif (newSelected.has(index)) {\n\t\t\tnewSelected.delete(index);\n\t\t} else {\n\t\t\tnewSelected.add(index);\n\t\t}\n\t\tsetSelectedRepos(newSelected);\n\t}\n\n\t// Render API key input step\n\tif (step === \"api-key\") {\n\t\treturn (\n\t\t\t<Box flexDirection=\"column\" paddingY={1}>\n\t\t\t\t<Box marginBottom={1}>\n\t\t\t\t\t<Text bold color=\"cyan\">\n\t\t\t\t\t\t{\"═══ GitHub App Setup ═══\"}\n\t\t\t\t\t</Text>\n\t\t\t\t</Box>\n\n\t\t\t\t<Box marginBottom={1}>\n\t\t\t\t\t<Text>Enter your Codowave API key:</Text>\n\t\t\t\t</Box>\n\n\t\t\t\t<Box>\n\t\t\t\t\t<Text color=\"gray\">{\"> \"}</Text>\n\t\t\t\t\t<Text>{apiKey}</Text>\n\t\t\t\t\t<Text color=\"cyan\">_</Text>\n\t\t\t\t</Box>\n\n\t\t\t\t{error && (\n\t\t\t\t\t<Box marginTop={1}>\n\t\t\t\t\t\t<Text color=\"red\">{pc.red(\"✖ \" + error)}</Text>\n\t\t\t\t\t</Box>\n\t\t\t\t)}\n\n\t\t\t\t<Box marginTop={1}>\n\t\t\t\t\t<Text color=\"gray\">\n\t\t\t\t\t\tPress <Text bold>Enter</Text> to continue, <Text bold>Esc</Text> to cancel\n\t\t\t\t\t</Text>\n\t\t\t\t</Box>\n\t\t\t</Box>\n\t\t);\n\t}\n\n\t// Render repository selection step\n\tif (step === \"repos\") {\n\t\treturn (\n\t\t\t<Box flexDirection=\"column\" paddingY={1}>\n\t\t\t\t<Box marginBottom={1}>\n\t\t\t\t\t<Text bold color=\"cyan\">\n\t\t\t\t\t\t{\"═══ Select Repositories ═══\"}\n\t\t\t\t\t</Text>\n\t\t\t\t</Box>\n\n\t\t\t\t{loading && (\n\t\t\t\t\t<Box>\n\t\t\t\t\t\t<Text color=\"yellow\">\n\t\t\t\t\t\t\t<Spinner type=\"dots\" /> Loading repositories...\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t</Box>\n\t\t\t\t)}\n\n\t\t\t\t{error && (\n\t\t\t\t\t<Box marginBottom={1}>\n\t\t\t\t\t\t<Text color=\"red\">{pc.red(\"✖ \" + error)}</Text>\n\t\t\t\t\t</Box>\n\t\t\t\t)}\n\n\t\t\t\t{!loading && !error && repos.length === 0 && (\n\t\t\t\t\t<Box marginBottom={1}>\n\t\t\t\t\t\t<Text color=\"yellow\">No repositories found for this API key.</Text>\n\t\t\t\t\t</Box>\n\t\t\t\t)}\n\n\t\t\t\t{!loading && repos.length > 0 && (\n\t\t\t\t\t<Box flexDirection=\"column\" marginBottom={1}>\n\t\t\t\t\t\t{repos.map((repo, index) => (\n\t\t\t\t\t\t\t<Box key={index}>\n\t\t\t\t\t\t\t\t<Text>{index === currentSelection ? \" > \" : \" \"}</Text>\n\t\t\t\t\t\t\t\t<Text color={selectedRepos.has(index) ? \"green\" : \"gray\"}>\n\t\t\t\t\t\t\t\t\t[{selectedRepos.has(index) ? \"✓\" : \" \"}]\n\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t<Text> </Text>\n\t\t\t\t\t\t\t\t<Text bold={index === currentSelection}>\n\t\t\t\t\t\t\t\t\t<Text dimColor={!selectedRepos.has(index)}>\n\t\t\t\t\t\t\t\t\t\t{repo.owner}/{repo.name}\n\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t</Box>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</Box>\n\t\t\t\t)}\n\n\t\t\t\t{!loading && repos.length > 0 && (\n\t\t\t\t\t<Box marginTop={1}>\n\t\t\t\t\t\t<Text color=\"gray\">\n\t\t\t\t\t\t\t<Text bold>↑/↓</Text> navigate | <Text bold>Space</Text> toggle | <Text bold>A</Text> all | <Text bold>N</Text> none\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t</Box>\n\t\t\t\t)}\n\n\t\t\t\t<Box marginTop={1}>\n\t\t\t\t\t<Text color=\"gray\">\n\t\t\t\t\t\tSelected: <Text bold color=\"green\">{selectedRepos.size}</Text> / {repos.length} repos | <Text bold>Enter</Text> confirm | <Text bold>Esc</Text> back\n\t\t\t\t\t</Text>\n\t\t\t\t</Box>\n\t\t\t</Box>\n\t\t);\n\t}\n\n\treturn null;\n};\n","import { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { readConfig, type CodowaveConfig } from \"../config.js\";\nimport { getRun, type RunStatus, type RunStage } from \"./status.js\";\n\n// Demo runs store (in production, this would be from API)\nconst demoRuns: Map<string, RunStatus> = new Map();\n\nfunction parseIssue(input: string): { owner: string; repo: string; number: number } | null {\n // Match: https://github.com/owner/repo/issues/123\n const urlMatch = input.match(/github\\.com\\/([^/]+)\\/([^/]+)\\/issues\\/(\\d+)/);\n if (urlMatch && urlMatch[1] && urlMatch[2] && urlMatch[3]) {\n return { owner: urlMatch[1], repo: urlMatch[2], number: parseInt(urlMatch[3], 10) };\n }\n\n // Match: owner/repo#123\n const repoMatch = input.match(/([^/]+)\\/([^#]+)#(\\d+)/);\n if (repoMatch && repoMatch[1] && repoMatch[2] && repoMatch[3]) {\n return { owner: repoMatch[1], repo: repoMatch[2], number: parseInt(repoMatch[3], 10) };\n }\n\n // Match: just issue number (123)\n const numMatch = input.match(/^(\\d+)$/);\n if (numMatch && numMatch[1]) {\n return { owner: \"\", repo: \"\", number: parseInt(numMatch[1], 10) };\n }\n\n return null;\n}\n\nasync function triggerRun(\n config: CodowaveConfig,\n issue: { owner: string; repo: string; number: number }\n): Promise<string> {\n const apiUrl = config.apiUrl;\n const apiKey = config.apiKey;\n\n // Find repo in config\n const repoConfig = config.repos.find(\n (r) => r.owner === issue.owner && r.name === issue.repo\n );\n\n if (!repoConfig) {\n throw new Error(\n `Repository ${issue.owner}/${issue.repo} not configured. Run \\`codowave config add-repo ${issue.owner}/${issue.repo}\\``\n );\n }\n\n // Call the API to trigger a run\n const response = await fetch(`${apiUrl}/api/runs`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n repositoryId: repoConfig.id,\n issueNumber: issue.number,\n }),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Failed to trigger run: ${response.status} ${error}`);\n }\n\n const data = await response.json() as { runId: string };\n return data.runId;\n}\n\nfunction createDemoRun(issue: { owner: string; repo: string; number: number }): RunStatus {\n const runId = `run-${Date.now()}`;\n const run: RunStatus = {\n id: runId,\n repo: issue.owner && issue.repo ? `${issue.owner}/${issue.repo}` : \"CodowaveAI/Codowave\",\n status: \"in_progress\",\n issue: `#${issue.number}`,\n branchName: `agent/issue-${issue.number}`,\n startedAt: new Date().toISOString(),\n stages: [\n { name: \"context\", status: \"pending\" },\n { name: \"planning\", status: \"pending\" },\n { name: \"implementation\", status: \"pending\" },\n { name: \"testing\", status: \"pending\" },\n { name: \"pr-creation\", status: \"pending\" },\n ],\n };\n demoRuns.set(runId, run);\n return run;\n}\n\nfunction streamDemoRun(run: RunStatus) {\n // Simulate SSE streaming with demo data\n const stages = [\"context\", \"planning\", \"implementation\", \"testing\", \"pr-creation\"];\n let currentStage = 0;\n\n console.log(pc.bold(\"\\n=== Starting Run ===\\n\"));\n console.log(pc.bold(\"Run ID: \") + run.id);\n console.log(pc.bold(\"Repo: \") + run.repo);\n console.log(pc.bold(\"Issue: \") + run.issue);\n console.log(pc.bold(\"Branch: \") + run.branchName);\n console.log(\"\");\n\n const interval = setInterval(() => {\n if (currentStage >= stages.length) {\n clearInterval(interval);\n \n // Mark run as completed\n run.status = \"completed\";\n run.completedAt = new Date().toISOString();\n run.prNumber = 100 + Math.floor(Math.random() * 50);\n run.prTitle = `feat: Implement issue #${run.issue}`;\n \n console.log(pc.green(\"\\n✓ Run completed successfully!\"));\n console.log(pc.bold(\"\\n=== Result ===\\n\"));\n console.log(pc.bold(\"PR: \") + `#${run.prNumber} - ${run.prTitle}`);\n console.log(pc.bold(\"Branch: \") + run.branchName);\n console.log(\"\");\n process.exit(0);\n return;\n }\n\n const stageName = stages[currentStage];\n const stage = run.stages.find((s) => s.name === stageName);\n \n if (stage) {\n stage.status = \"running\";\n \n // Show stage progress\n console.log(pc.blue(`\\n--- ${stageName} ---`));\n \n // Simulate work and mark complete\n setTimeout(() => {\n stage.status = \"completed\";\n stage.logs = `${stageName} completed successfully`;\n \n // Move to next stage\n currentStage++;\n }, 1000 + Math.random() * 2000);\n } else {\n currentStage++;\n }\n }, 500);\n\n // Handle Ctrl+C\n process.on(\"SIGINT\", () => {\n clearInterval(interval);\n run.status = \"cancelled\";\n console.log(pc.yellow(\"\\n\\n⚠ Run cancelled\"));\n process.exit(1);\n });\n}\n\nexport const runCommand = new Command(\"run\")\n .description(\"Trigger Codowave to process a GitHub issue\")\n .argument(\"<issue>\", \"GitHub issue number, URL (https://github.com/owner/repo/issues/123), or owner/repo#123\")\n .option(\"-r, --repo <owner/repo>\", \"Target repository (e.g. owner/repo)\")\n .option(\"-s, --stream\", \"Stream run progress (SSE)\", false)\n .action(async (_issueArg: string, _options: { repo?: string; stream?: boolean }) => {\n try {\n // Parse the issue\n const parsed = parseIssue(_issueArg);\n \n if (!parsed) {\n console.error(pc.red(\"Invalid issue format. Use:\"));\n console.error(\" - Issue number: 123\");\n console.error(\" - Full URL: https://github.com/owner/repo/issues/123\");\n console.error(\" - Short form: owner/repo#123\");\n process.exit(1);\n }\n\n // If repo is specified via option, override\n if (_options.repo) {\n const parts = _options.repo.split(\"/\");\n const owner = parts[0] || \"\";\n const repo = parts[1] || \"\";\n parsed.owner = owner;\n parsed.repo = repo;\n }\n\n // Try to read config\n let config: CodowaveConfig | null = null;\n try {\n config = readConfig();\n } catch {\n // Config not required for demo mode\n }\n\n // Check if we have a real config (API mode) or running in demo mode\n if (config && config.apiKey && config.repos.length > 0) {\n // Real API mode\n console.log(pc.blue(\"Connecting to Codowave API...\"));\n \n // Validate repo is configured\n if (!parsed.owner || !parsed.repo) {\n console.error(pc.red(\"Repository required. Use -r option or include in issue URL.\"));\n process.exit(1);\n }\n\n const runId = await triggerRun(config, parsed);\n console.log(pc.green(`✓ Run triggered: ${runId}`));\n \n if (_options.stream) {\n console.log(pc.blue(\"\\nStreaming run progress...\"));\n // In production, this would connect to SSE endpoint\n // const eventSource = new EventSource(`${config.apiUrl}/api/runs/${runId}/events`);\n } else {\n console.log(pc.gray(`\\nRun started. Use \\`codowave status ${runId}\\` to check progress.`));\n }\n } else {\n // Demo mode\n console.log(pc.yellow(\"⚠ No config found. Running in demo mode.\\n\"));\n \n const run = createDemoRun(parsed);\n \n if (_options.stream || !process.stdout.isTTY) {\n // Stream mode\n streamDemoRun(run);\n } else {\n // Non-stream mode - just show the run info\n console.log(pc.green(`✓ Run started: ${run.id}`));\n console.log(pc.gray(`\\nUse \\`codowave status ${run.id}\\` to check progress.`));\n console.log(pc.gray(`Use \\`codowave logs ${run.id} -f\\` to follow logs.`));\n }\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.error(pc.red(`\\n✖ Error: ${message}\\n`));\n process.exit(1);\n }\n });\n","import { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { readConfig } from \"../config.js\";\n\n// In-memory run store for demo (would be API calls in production)\nexport interface RunStatus {\n id: string;\n repo: string;\n status: \"pending\" | \"in_progress\" | \"completed\" | \"failed\" | \"cancelled\";\n issue: string;\n prNumber?: number;\n prTitle?: string;\n branchName?: string;\n startedAt?: string;\n completedAt?: string;\n errorMessage?: string;\n stages: RunStage[];\n}\n\nexport interface RunStage {\n name: string;\n status: \"pending\" | \"running\" | \"completed\" | \"failed\" | \"skipped\";\n logs?: string;\n}\n\n// Demo data store (would be API in production)\nconst demoRuns: Map<string, RunStatus> = new Map();\n\n// Initialize with some demo data\nfunction initDemoData() {\n if (demoRuns.size === 0) {\n const demoRun: RunStatus = {\n id: \"latest\",\n repo: \"CodowaveAI/Codowave\",\n status: \"in_progress\",\n issue: \"#53: Implement CLI status and logs commands\",\n branchName: \"agent/issue-53\",\n startedAt: new Date(Date.now() - 5 * 60 * 1000).toISOString(),\n stages: [\n { name: \"context\", status: \"completed\", logs: \"Loaded 12 files, 3 PRs context\" },\n { name: \"planning\", status: \"completed\", logs: \"Generated implementation plan\" },\n { name: \"implementation\", status: \"running\", logs: \"Implementing status command...\" },\n { name: \"testing\", status: \"pending\" },\n { name: \"pr-creation\", status: \"pending\" },\n ],\n };\n demoRuns.set(demoRun.id, demoRun);\n \n // Also add a completed run\n const completedRun: RunStatus = {\n id: \"abc-123-def\",\n repo: \"CodowaveAI/Codowave\",\n status: \"completed\",\n issue: \"#52: Add authentication flow\",\n prNumber: 78,\n prTitle: \"feat: Add OAuth authentication flow\",\n branchName: \"feat/auth-flow\",\n startedAt: new Date(Date.now() - 60 * 60 * 1000).toISOString(),\n completedAt: new Date(Date.now() - 45 * 60 * 1000).toISOString(),\n stages: [\n { name: \"context\", status: \"completed\" },\n { name: \"planning\", status: \"completed\" },\n { name: \"implementation\", status: \"completed\" },\n { name: \"testing\", status: \"completed\" },\n { name: \"pr-creation\", status: \"completed\" },\n ],\n };\n demoRuns.set(completedRun.id, completedRun);\n }\n}\n\nexport function getRun(runId?: string): RunStatus | undefined {\n initDemoData();\n if (!runId) {\n // Return most recent run\n return Array.from(demoRuns.values()).sort((a, b) => \n new Date(b.startedAt || 0).getTime() - new Date(a.startedAt || 0).getTime()\n )[0];\n }\n return demoRuns.get(runId);\n}\n\nfunction formatStatus(status: RunStatus[\"status\"]): string {\n switch (status) {\n case \"pending\":\n return pc.gray(\"pending\");\n case \"in_progress\":\n return pc.blue(\"in_progress\");\n case \"completed\":\n return pc.green(\"completed\");\n case \"failed\":\n return pc.red(\"failed\");\n case \"cancelled\":\n return pc.gray(\"cancelled\");\n default:\n return pc.gray(status);\n }\n}\n\nfunction formatStageStatus(status: RunStage[\"status\"]): string {\n switch (status) {\n case \"pending\":\n return pc.gray(\"[ ]\");\n case \"running\":\n return pc.blue(\"[~]\");\n case \"completed\":\n return pc.green(\"[+]\");\n case \"failed\":\n return pc.red(\"[x]\");\n case \"skipped\":\n return pc.gray(\"[-]\");\n default:\n return pc.gray(\"[?]\");\n }\n}\n\nfunction formatDuration(startedAt?: string, completedAt?: string): string {\n if (!startedAt) return \"\";\n const start = new Date(startedAt).getTime();\n const end = completedAt ? new Date(completedAt).getTime() : Date.now();\n const seconds = Math.floor((end - start) / 1000);\n \n if (seconds < 60) return `${seconds}s`;\n const minutes = Math.floor(seconds / 60);\n const remainingSeconds = seconds % 60;\n if (minutes < 60) return `${minutes}m ${remainingSeconds}s`;\n const hours = Math.floor(minutes / 60);\n const remainingMinutes = minutes % 60;\n return `${hours}h ${remainingMinutes}m`;\n}\n\nexport const statusCommand = new Command(\"status\")\n .description(\"Show the status of a Codowave run\")\n .argument(\"[run-id]\", \"Run ID (defaults to latest)\")\n .option(\"-r, --repo <owner/repo>\", \"Filter by repository\")\n .action(async (_runId?: string, _options?: { repo?: string }) => {\n try {\n // Try to read config (for future API integration)\n let config;\n try {\n config = readConfig();\n } catch {\n // Config not required for demo mode\n }\n\n const run = getRun(_runId);\n \n if (!run) {\n console.log(pc.yellow(\"No runs found. Run `codowave run <issue>` to start a new run.\"));\n return;\n }\n\n // Filter by repo if specified\n if (_options?.repo && run.repo !== _options.repo) {\n console.log(pc.yellow(\"No run found for repository \" + _options.repo));\n return;\n }\n\n console.log(pc.bold(\"\\n=== Run Status ===\\n\"));\n console.log(pc.bold(\"ID: \") + run.id);\n console.log(pc.bold(\"Repo: \") + run.repo);\n console.log(pc.bold(\"Issue: \") + run.issue);\n console.log(pc.bold(\"Status: \") + formatStatus(run.status));\n console.log(pc.bold(\"Branch: \") + (run.branchName || pc.gray(\"(none)\")));\n \n if (run.prNumber) {\n console.log(pc.bold(\"PR: \") + \"#\" + run.prNumber + \" - \" + (run.prTitle || \"\"));\n }\n \n if (run.startedAt) {\n console.log(pc.bold(\"Started: \") + new Date(run.startedAt).toLocaleString());\n }\n \n if (run.completedAt) {\n console.log(pc.bold(\"Duration: \") + formatDuration(run.startedAt, run.completedAt));\n } else if (run.startedAt) {\n console.log(pc.bold(\"Duration: \") + pc.blue(\"running... \") + formatDuration(run.startedAt));\n }\n \n if (run.errorMessage) {\n console.log(pc.bold(\"Error: \") + pc.red(run.errorMessage));\n }\n\n console.log(pc.bold(\"\\n=== Stages ===\\n\"));\n for (const stage of run.stages) {\n const statusIcon = formatStageStatus(stage.status);\n const statusText = pc.bold(\"[\" + stage.status + \"]\");\n console.log(\" \" + statusIcon + \" \" + pc.bold(stage.name.padEnd(20)) + \" \" + statusText);\n }\n\n console.log(\"\");\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.error(pc.red(\"\\n=== Error: \" + message + \" ===\\n\"));\n process.exit(1);\n }\n });\n","import { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { readConfig } from \"../config.js\";\nimport { getRun, type RunStatus } from \"./status.js\";\n\nexport const logsCommand = new Command(\"logs\")\n .description(\"Stream logs for a Codowave run\")\n .argument(\"[run-id]\", \"Run ID (defaults to latest)\")\n .option(\"-f, --follow\", \"Follow log output (SSE stream)\")\n .option(\"-s, --stage <name>\", \"Show logs for a specific stage\")\n .option(\"--no-color\", \"Disable colored output\")\n .action(async (_runId?: string, _options?: { follow?: boolean; stage?: string; color?: boolean }) => {\n try {\n // Try to read config (for future API integration)\n let config;\n try {\n config = readConfig();\n } catch {\n // Config not required for demo mode\n }\n\n const run: RunStatus | undefined = getRun(_runId);\n \n if (!run) {\n console.log(pc.yellow(\"No runs found. Run `codowave run <issue>` to start a new run.\"));\n return;\n }\n\n // If --stage is specified, show only that stage's logs\n if (_options?.stage) {\n const stage = run.stages.find((s: { name: string }) => s.name === _options.stage);\n if (!stage) {\n console.log(pc.red(\"Stage \\\"\" + _options.stage + \"\\\" not found.\"));\n console.log(pc.gray(\"Available stages: \") + run.stages.map((s: { name: string }) => s.name).join(\", \"));\n return;\n }\n \n console.log(pc.bold(\"\\n=== Logs: \" + stage.name + \" ===\\n\"));\n console.log(pc.bold(\"Status: \") + stage.status);\n \n if (stage.logs) {\n console.log(pc.gray(\"\\n--- Output ---\\n\"));\n console.log(stage.logs);\n } else {\n console.log(pc.gray(\"\\n(no logs available yet)\"));\n }\n \n // If following and stage is still running, simulate live logs\n if (_options.follow && stage.status === \"running\") {\n console.log(pc.blue(\"\\n--- Following live logs (Ctrl+C to exit) ---\\n\"));\n // In production, this would connect to SSE endpoint\n // For demo, we'll show a message\n console.log(pc.gray(\"(Live streaming would connect to API SSE endpoint in production)\"));\n }\n console.log(\"\");\n return;\n }\n\n // Otherwise show all stage logs\n console.log(pc.bold(\"\\n=== Logs: \" + run.id + \" ===\\n\"));\n console.log(pc.bold(\"Issue: \") + run.issue);\n console.log(pc.bold(\"Status: \") + run.status);\n console.log(\"\");\n\n for (const stage of run.stages) {\n const statusIcon = stage.status === \"completed\" ? \"[+]\" : \n stage.status === \"failed\" ? \"[x]\" :\n stage.status === \"running\" ? \"[~]\" : \"[ ]\";\n \n console.log(pc.bold(\"\\n\" + statusIcon + \" \" + stage.name + \"\\n\"));\n \n if (stage.logs) {\n console.log(stage.logs);\n } else if (stage.status === \"pending\") {\n console.log(pc.gray(\"(pending)\"));\n } else if (stage.status === \"running\") {\n console.log(pc.blue(\"(running...)\"));\n } else if (stage.status === \"skipped\") {\n console.log(pc.gray(\"(skipped)\"));\n }\n }\n\n // If following and run is still in progress, simulate live output\n if (_options?.follow && run.status === \"in_progress\") {\n console.log(pc.blue(\"\\n--- Following live logs (Ctrl+C to exit) ---\\n\"));\n // In production, this would connect to SSE endpoint\n console.log(pc.gray(\"(Live streaming would connect to API SSE endpoint in production)\"));\n \n // Simulate periodic updates (for demo purposes)\n let dots = 0;\n const interval = setInterval(() => {\n dots = (dots + 1) % 4;\n process.stdout.write(pc.blue(\"\\r\" + \" \".repeat(dots) + \" waiting for updates...\"));\n }, 500);\n \n // Handle Ctrl+C\n process.on(\"SIGINT\", () => {\n clearInterval(interval);\n console.log(pc.gray(\"\\n\\n(Stopped following)\"));\n process.exit(0);\n });\n }\n\n console.log(\"\");\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.error(pc.red(\"\\n=== Error: \" + message + \" ===\\n\"));\n process.exit(1);\n }\n });\n","import { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { readConfig, readConfigOrThrow, updateConfig, getConfigPath } from \"../config.js\";\n\nexport const configCommand = new Command(\"config\")\n .description(\"Get or set Codowave configuration values\");\n\n// List all available config options\nconfigCommand\n .command(\"list\")\n .description(\"List all available config options\")\n .action(() => {\n console.log(pc.bold(\"\\n📋 Available Config Options:\\n\"));\n console.log(` ${pc.cyan(\"apiKey\")} ${pc.gray(\"— Your Codowave API key\")}`);\n console.log(` ${pc.cyan(\"apiUrl\")} ${pc.gray(\"— API endpoint URL (default: https://api.codowave.com)\")}`);\n console.log(` ${pc.cyan(\"repos\")} ${pc.gray(\"— List of configured repositories\")}`);\n console.log(` ${pc.cyan(\"configPath\")} ${pc.gray(\"— Path to the config file\")}`);\n console.log(\"\");\n });\n\n// Get a config value\nconfigCommand\n .command(\"get <key>\")\n .description(\"Get a config value\")\n .action((key: string) => {\n try {\n const config = readConfigOrThrow();\n \n // Special case for configPath\n if (key === \"configPath\") {\n console.log(pc.green(getConfigPath()));\n return;\n }\n \n // Special case for repos - show nicely formatted\n if (key === \"repos\") {\n if (config.repos.length === 0) {\n console.log(pc.yellow(\"No repos configured.\"));\n } else {\n console.log(pc.bold(\"\\n📦 Configured Repositories:\\n\"));\n config.repos.forEach((repo, index) => {\n console.log(` ${index + 1}. ${pc.cyan(`${repo.owner}/${repo.name}`)}`);\n if (repo.id) {\n console.log(` ${pc.gray(\"ID: \" + repo.id)}`);\n }\n });\n console.log(\"\");\n }\n return;\n }\n \n // Get a specific key\n const value = config[key as keyof typeof config];\n \n if (value === undefined) {\n console.error(pc.red(`✖ Unknown config key: ${key}`));\n console.log(pc.gray(` Run \\`codowave config list\\` to see available options.`));\n process.exit(1);\n }\n \n console.log(value);\n } catch (err) {\n console.error(pc.red(`✖ ${err instanceof Error ? err.message : String(err)}`));\n process.exit(1);\n }\n });\n\n// Set a config value\nconfigCommand\n .command(\"set <key> <value>\")\n .description(\"Set a config value\")\n .action((key: string, value: string) => {\n try {\n // Validate the key\n const validKeys = [\"apiKey\", \"apiUrl\"];\n if (!validKeys.includes(key)) {\n console.error(pc.red(`✖ Cannot set '${key}' directly.`));\n console.log(pc.gray(` For 'repos', use \\`codowave init\\` to manage repositories.`));\n console.log(pc.gray(` Run \\`codowave config list\\` to see available options.`));\n process.exit(1);\n }\n \n // Validate apiUrl if provided\n if (key === \"apiUrl\") {\n try {\n new URL(value);\n } catch {\n console.error(pc.red(`✖ Invalid URL: ${value}`));\n process.exit(1);\n }\n }\n \n const updates = { [key]: value };\n const newConfig = updateConfig(updates);\n \n console.log(pc.green(`✓ Updated ${key}`));\n \n // Show the new value\n console.log(pc.gray(` ${key} = ${newConfig[key as keyof typeof newConfig]}`));\n } catch (err) {\n console.error(pc.red(`✖ ${err instanceof Error ? err.message : String(err)}`));\n process.exit(1);\n }\n });\n\n// Show all current config values (alias for showing full config)\nconfigCommand\n .command(\"show\")\n .description(\"Show all current config values\")\n .action(() => {\n try {\n const config = readConfigOrThrow();\n \n console.log(pc.bold(\"\\n⚙️ Current Configuration:\\n\"));\n console.log(` ${pc.cyan(\"apiKey\")}: ${config.apiKey ? pc.green(\"••••••••\") + pc.gray(\" (hidden)\") : pc.yellow(\"not set\")}`);\n console.log(` ${pc.cyan(\"apiUrl\")}: ${config.apiUrl}`);\n console.log(` ${pc.cyan(\"repos\")}: ${config.repos.length} repository(s) configured`);\n console.log(` ${pc.cyan(\"configPath\")}: ${pc.gray(getConfigPath())}`);\n \n if (config.repos.length > 0) {\n console.log(pc.bold(pc.gray(\"\\n Repositories:\")));\n config.repos.forEach((repo) => {\n console.log(` • ${repo.owner}/${repo.name}${repo.id ? pc.gray(` (${repo.id})`) : \"\"}`);\n });\n }\n \n console.log(\"\");\n } catch (err) {\n console.error(pc.red(`✖ ${err instanceof Error ? err.message : String(err)}`));\n process.exit(1);\n }\n });\n\n// Default action when just 'config' is run - show help\nconfigCommand.action(() => {\n configCommand.help();\n});\n","import { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { readConfig, updateConfig, getConfigPath } from \"../config.js\";\n\nconst PRO_API_URL = \"https://api.codowave.com\";\nconst PRO_AUTH_URL = \"https://codowave.com/api/auth/device\";\nconst PRO_TOKEN_URL = \"https://codowave.com/api/auth/token\";\n\nexport const connectCommand = new Command(\"connect\")\n .description(\"Connect to Codowave Pro (upgrade from OSS)\")\n .action(async () => {\n try {\n console.log(pc.bold(\"\\n🔗 Codowave Connect\\n\"));\n console.log(pc.gray(\"This command upgrades your OSS installation to Codowave Pro.\\n\"));\n\n // Check current config\n const config = readConfig();\n const isAlreadyPro = config?.apiUrl === PRO_API_URL;\n\n if (isAlreadyPro) {\n console.log(pc.green(\"✓ You are already connected to Codowave Pro!\"));\n console.log(pc.gray(` API URL: ${config?.apiUrl}`));\n console.log(\"\");\n return;\n }\n\n // Start OAuth device flow\n console.log(pc.blue(\"Starting OAuth device flow...\\n\"));\n\n // In a real implementation, this would:\n // 1. Call PRO_AUTH_URL to get device_code, user_code, verification_uri\n // 2. Display user_code and verification_uri for user to enter in browser\n // 3. Poll PRO_TOKEN_URL until user authorizes\n // 4. Get access_token and store in config\n\n // For now, simulate the flow\n console.log(pc.gray(\" 1. Requesting device code...\"));\n \n // Simulate API call (would be real fetch in production)\n const deviceCode = `CODOWAVE-${Date.now().toString(36).toUpperCase()}`;\n const verificationUri = \"https://codowave.com/activate\";\n \n console.log(pc.green(\"\\n ⚠️ Device Code: \") + pc.bold(deviceCode));\n console.log(pc.gray(\"\\n 2. Please visit: \") + pc.cyan(verificationUri));\n console.log(pc.gray(\" and enter the device code above.\\n\"));\n \n console.log(pc.yellow(\" ℹ️ This is a stub implementation.\"));\n console.log(pc.gray(\" In production, this would poll for OAuth completion.\\n\"));\n\n // For demo purposes, let's just show what would happen\n console.log(pc.blue(\" 3. Would save Pro token and switch API URL...\\n\"));\n \n // Actually, let's not modify config in demo mode - just show what would happen\n console.log(pc.bold(\"What would happen:\\n\"));\n console.log(` • Save Pro API token to ${getConfigPath()}`);\n console.log(` • Set apiUrl to ${PRO_API_URL}`);\n console.log(\"\");\n \n console.log(pc.gray(\"Run with \") + pc.cyan(\"CODOWAVE_CONNECT=1\") + pc.gray(\" to enable (not implemented yet)\"));\n console.log(\"\");\n\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.error(pc.red(`\\n✖ Error: ${message}\\n`));\n process.exit(1);\n }\n });\n\n/**\n * Actually perform the connection (used after OAuth success)\n * This would be called internally after OAuth polling succeeds\n */\nexport async function performConnect(accessToken: string): Promise<void> {\n const config = updateConfig({\n apiKey: accessToken,\n apiUrl: PRO_API_URL,\n });\n \n console.log(pc.green(\"✓ Connected to Codowave Pro!\"));\n console.log(pc.gray(` API URL: ${config.apiUrl}`));\n}\n"],"mappings":"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","names":["Command","pc","jsx","pc","Command","pc","pc","Command","Command","pc","demoRuns","pc","Command","Command","pc","Command","pc","Command","pc","Command","pc","Command","pc","Command","pc","require","Command"]}
package/package.json CHANGED
@@ -1,22 +1,20 @@
1
1
  {
2
2
  "name": "codowave",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "Codowave OSS CLI — AI-powered coding agent for your GitHub repos",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "bin": {
8
- "codowave": "./dist/index.js"
8
+ "codowave": "./dist/cli.js"
9
9
  },
10
10
  "files": [
11
11
  "dist"
12
12
  ],
13
13
  "scripts": {
14
- "build": "tsup src/index.ts --format esm --dts --clean --banner.js '#!/usr/bin/env node'",
14
+ "build": "tsup src/index.ts --format esm --dts --clean",
15
15
  "dev": "tsup src/index.ts --format esm --watch",
16
16
  "typecheck": "tsc --noEmit",
17
- "lint": "eslint src --ext .ts,.tsx",
18
- "test": "vitest run",
19
- "test:watch": "vitest"
17
+ "test": "vitest run"
20
18
  },
21
19
  "dependencies": {
22
20
  "commander": "^12.1.0",