@waniwani/cli 0.0.5 → 0.0.10
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 +301 -158
- package/dist/index.js.map +1 -1
- package/package.json +59 -59
package/dist/index.js
CHANGED
|
@@ -1,117 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
|
-
import { Command as
|
|
5
|
-
|
|
6
|
-
// src/commands/login.ts
|
|
7
|
-
import { spawn } from "child_process";
|
|
8
|
-
import { createServer } from "http";
|
|
9
|
-
import chalk3 from "chalk";
|
|
10
|
-
import { Command } from "commander";
|
|
11
|
-
import ora from "ora";
|
|
4
|
+
import { Command as Command16 } from "commander";
|
|
12
5
|
|
|
13
|
-
// src/
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
6
|
+
// src/commands/init.ts
|
|
7
|
+
import { existsSync } from "fs";
|
|
8
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
16
9
|
import { join } from "path";
|
|
17
|
-
import {
|
|
18
|
-
var CONFIG_DIR = join(homedir(), ".waniwani");
|
|
19
|
-
var AUTH_FILE = join(CONFIG_DIR, "auth.json");
|
|
20
|
-
var AuthStoreSchema = z.object({
|
|
21
|
-
accessToken: z.string().nullable().default(null),
|
|
22
|
-
refreshToken: z.string().nullable().default(null),
|
|
23
|
-
expiresAt: z.string().nullable().default(null)
|
|
24
|
-
});
|
|
25
|
-
var API_BASE_URL = process.env.WANIWANI_API_URL || "https://waniwani.com";
|
|
26
|
-
async function ensureConfigDir() {
|
|
27
|
-
await mkdir(CONFIG_DIR, { recursive: true });
|
|
28
|
-
}
|
|
29
|
-
async function readAuthStore() {
|
|
30
|
-
await ensureConfigDir();
|
|
31
|
-
try {
|
|
32
|
-
await access(AUTH_FILE);
|
|
33
|
-
const content = await readFile(AUTH_FILE, "utf-8");
|
|
34
|
-
return AuthStoreSchema.parse(JSON.parse(content));
|
|
35
|
-
} catch {
|
|
36
|
-
return AuthStoreSchema.parse({});
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
async function writeAuthStore(store) {
|
|
40
|
-
await ensureConfigDir();
|
|
41
|
-
await writeFile(AUTH_FILE, JSON.stringify(store, null, 2), "utf-8");
|
|
42
|
-
}
|
|
43
|
-
var AuthManager = class {
|
|
44
|
-
storeCache = null;
|
|
45
|
-
async getStore() {
|
|
46
|
-
if (!this.storeCache) {
|
|
47
|
-
this.storeCache = await readAuthStore();
|
|
48
|
-
}
|
|
49
|
-
return this.storeCache;
|
|
50
|
-
}
|
|
51
|
-
async saveStore(store) {
|
|
52
|
-
this.storeCache = store;
|
|
53
|
-
await writeAuthStore(store);
|
|
54
|
-
}
|
|
55
|
-
async isLoggedIn() {
|
|
56
|
-
const store = await this.getStore();
|
|
57
|
-
return !!store.accessToken;
|
|
58
|
-
}
|
|
59
|
-
async getAccessToken() {
|
|
60
|
-
const store = await this.getStore();
|
|
61
|
-
return store.accessToken;
|
|
62
|
-
}
|
|
63
|
-
async getRefreshToken() {
|
|
64
|
-
const store = await this.getStore();
|
|
65
|
-
return store.refreshToken;
|
|
66
|
-
}
|
|
67
|
-
async setTokens(accessToken, refreshToken, expiresIn) {
|
|
68
|
-
const expiresAt = new Date(Date.now() + expiresIn * 1e3).toISOString();
|
|
69
|
-
const store = await this.getStore();
|
|
70
|
-
store.accessToken = accessToken;
|
|
71
|
-
store.refreshToken = refreshToken;
|
|
72
|
-
store.expiresAt = expiresAt;
|
|
73
|
-
await this.saveStore(store);
|
|
74
|
-
}
|
|
75
|
-
async clear() {
|
|
76
|
-
const emptyStore = AuthStoreSchema.parse({});
|
|
77
|
-
await this.saveStore(emptyStore);
|
|
78
|
-
}
|
|
79
|
-
async isTokenExpired() {
|
|
80
|
-
const store = await this.getStore();
|
|
81
|
-
if (!store.expiresAt) return true;
|
|
82
|
-
return new Date(store.expiresAt).getTime() - 5 * 60 * 1e3 < Date.now();
|
|
83
|
-
}
|
|
84
|
-
async tryRefreshToken() {
|
|
85
|
-
const refreshToken = await this.getRefreshToken();
|
|
86
|
-
if (!refreshToken) return false;
|
|
87
|
-
try {
|
|
88
|
-
const response = await fetch(`${API_BASE_URL}/api/auth/oauth2/token`, {
|
|
89
|
-
method: "POST",
|
|
90
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
91
|
-
body: new URLSearchParams({
|
|
92
|
-
grant_type: "refresh_token",
|
|
93
|
-
refresh_token: refreshToken,
|
|
94
|
-
client_id: "waniwani-cli"
|
|
95
|
-
}).toString()
|
|
96
|
-
});
|
|
97
|
-
if (!response.ok) {
|
|
98
|
-
await this.clear();
|
|
99
|
-
return false;
|
|
100
|
-
}
|
|
101
|
-
const data = await response.json();
|
|
102
|
-
await this.setTokens(
|
|
103
|
-
data.access_token,
|
|
104
|
-
data.refresh_token,
|
|
105
|
-
data.expires_in
|
|
106
|
-
);
|
|
107
|
-
return true;
|
|
108
|
-
} catch {
|
|
109
|
-
await this.clear();
|
|
110
|
-
return false;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
var auth = new AuthManager();
|
|
10
|
+
import { Command } from "commander";
|
|
115
11
|
|
|
116
12
|
// src/lib/errors.ts
|
|
117
13
|
import chalk from "chalk";
|
|
@@ -237,6 +133,164 @@ function prettyPrint(data, indent = 0) {
|
|
|
237
133
|
}
|
|
238
134
|
}
|
|
239
135
|
|
|
136
|
+
// src/commands/init.ts
|
|
137
|
+
var PROJECT_CONFIG_DIR = ".waniwani";
|
|
138
|
+
var PROJECT_CONFIG_FILE = "settings.local.json";
|
|
139
|
+
var initCommand = new Command("init").description("Initialize WaniWani project config in current directory").action(async (_, command) => {
|
|
140
|
+
const globalOptions = command.optsWithGlobals();
|
|
141
|
+
const json = globalOptions.json ?? false;
|
|
142
|
+
try {
|
|
143
|
+
const cwd = process.cwd();
|
|
144
|
+
const configDir = join(cwd, PROJECT_CONFIG_DIR);
|
|
145
|
+
const configPath = join(configDir, PROJECT_CONFIG_FILE);
|
|
146
|
+
if (existsSync(configDir)) {
|
|
147
|
+
if (json) {
|
|
148
|
+
formatOutput(
|
|
149
|
+
{ initialized: false, message: "Already initialized" },
|
|
150
|
+
true
|
|
151
|
+
);
|
|
152
|
+
} else {
|
|
153
|
+
console.log("Project already initialized (.waniwani/ exists)");
|
|
154
|
+
}
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
await mkdir(configDir, { recursive: true });
|
|
158
|
+
const defaultConfig = {
|
|
159
|
+
mcpId: null,
|
|
160
|
+
defaults: {}
|
|
161
|
+
};
|
|
162
|
+
await writeFile(
|
|
163
|
+
configPath,
|
|
164
|
+
JSON.stringify(defaultConfig, null, " "),
|
|
165
|
+
"utf-8"
|
|
166
|
+
);
|
|
167
|
+
if (json) {
|
|
168
|
+
formatOutput({ initialized: true, path: configDir }, true);
|
|
169
|
+
} else {
|
|
170
|
+
formatSuccess("Initialized WaniWani project config", false);
|
|
171
|
+
console.log();
|
|
172
|
+
console.log(` Created: ${PROJECT_CONFIG_DIR}/${PROJECT_CONFIG_FILE}`);
|
|
173
|
+
console.log();
|
|
174
|
+
console.log("Now run:");
|
|
175
|
+
console.log(' waniwani mcp create "my-mcp"');
|
|
176
|
+
console.log(" waniwani mcp use <name>");
|
|
177
|
+
}
|
|
178
|
+
} catch (error) {
|
|
179
|
+
handleError(error, json);
|
|
180
|
+
process.exit(1);
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// src/commands/login.ts
|
|
185
|
+
import { spawn } from "child_process";
|
|
186
|
+
import { createServer } from "http";
|
|
187
|
+
import chalk3 from "chalk";
|
|
188
|
+
import { Command as Command2 } from "commander";
|
|
189
|
+
import ora from "ora";
|
|
190
|
+
|
|
191
|
+
// src/lib/auth.ts
|
|
192
|
+
import { access, mkdir as mkdir2, readFile, writeFile as writeFile2 } from "fs/promises";
|
|
193
|
+
import { homedir } from "os";
|
|
194
|
+
import { join as join2 } from "path";
|
|
195
|
+
import { z } from "zod";
|
|
196
|
+
var CONFIG_DIR = join2(homedir(), ".waniwani");
|
|
197
|
+
var AUTH_FILE = join2(CONFIG_DIR, "auth.json");
|
|
198
|
+
var AuthStoreSchema = z.object({
|
|
199
|
+
accessToken: z.string().nullable().default(null),
|
|
200
|
+
refreshToken: z.string().nullable().default(null),
|
|
201
|
+
expiresAt: z.string().nullable().default(null)
|
|
202
|
+
});
|
|
203
|
+
var API_BASE_URL = process.env.WANIWANI_API_URL || "https://waniwani.com";
|
|
204
|
+
async function ensureConfigDir() {
|
|
205
|
+
await mkdir2(CONFIG_DIR, { recursive: true });
|
|
206
|
+
}
|
|
207
|
+
async function readAuthStore() {
|
|
208
|
+
await ensureConfigDir();
|
|
209
|
+
try {
|
|
210
|
+
await access(AUTH_FILE);
|
|
211
|
+
const content = await readFile(AUTH_FILE, "utf-8");
|
|
212
|
+
return AuthStoreSchema.parse(JSON.parse(content));
|
|
213
|
+
} catch {
|
|
214
|
+
return AuthStoreSchema.parse({});
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
async function writeAuthStore(store) {
|
|
218
|
+
await ensureConfigDir();
|
|
219
|
+
await writeFile2(AUTH_FILE, JSON.stringify(store, null, 2), "utf-8");
|
|
220
|
+
}
|
|
221
|
+
var AuthManager = class {
|
|
222
|
+
storeCache = null;
|
|
223
|
+
async getStore() {
|
|
224
|
+
if (!this.storeCache) {
|
|
225
|
+
this.storeCache = await readAuthStore();
|
|
226
|
+
}
|
|
227
|
+
return this.storeCache;
|
|
228
|
+
}
|
|
229
|
+
async saveStore(store) {
|
|
230
|
+
this.storeCache = store;
|
|
231
|
+
await writeAuthStore(store);
|
|
232
|
+
}
|
|
233
|
+
async isLoggedIn() {
|
|
234
|
+
const store = await this.getStore();
|
|
235
|
+
return !!store.accessToken;
|
|
236
|
+
}
|
|
237
|
+
async getAccessToken() {
|
|
238
|
+
const store = await this.getStore();
|
|
239
|
+
return store.accessToken;
|
|
240
|
+
}
|
|
241
|
+
async getRefreshToken() {
|
|
242
|
+
const store = await this.getStore();
|
|
243
|
+
return store.refreshToken;
|
|
244
|
+
}
|
|
245
|
+
async setTokens(accessToken, refreshToken, expiresIn) {
|
|
246
|
+
const expiresAt = new Date(Date.now() + expiresIn * 1e3).toISOString();
|
|
247
|
+
const store = await this.getStore();
|
|
248
|
+
store.accessToken = accessToken;
|
|
249
|
+
store.refreshToken = refreshToken;
|
|
250
|
+
store.expiresAt = expiresAt;
|
|
251
|
+
await this.saveStore(store);
|
|
252
|
+
}
|
|
253
|
+
async clear() {
|
|
254
|
+
const emptyStore = AuthStoreSchema.parse({});
|
|
255
|
+
await this.saveStore(emptyStore);
|
|
256
|
+
}
|
|
257
|
+
async isTokenExpired() {
|
|
258
|
+
const store = await this.getStore();
|
|
259
|
+
if (!store.expiresAt) return true;
|
|
260
|
+
return new Date(store.expiresAt).getTime() - 5 * 60 * 1e3 < Date.now();
|
|
261
|
+
}
|
|
262
|
+
async tryRefreshToken() {
|
|
263
|
+
const refreshToken = await this.getRefreshToken();
|
|
264
|
+
if (!refreshToken) return false;
|
|
265
|
+
try {
|
|
266
|
+
const response = await fetch(`${API_BASE_URL}/api/auth/oauth2/token`, {
|
|
267
|
+
method: "POST",
|
|
268
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
269
|
+
body: new URLSearchParams({
|
|
270
|
+
grant_type: "refresh_token",
|
|
271
|
+
refresh_token: refreshToken,
|
|
272
|
+
client_id: "waniwani-cli"
|
|
273
|
+
}).toString()
|
|
274
|
+
});
|
|
275
|
+
if (!response.ok) {
|
|
276
|
+
await this.clear();
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
const data = await response.json();
|
|
280
|
+
await this.setTokens(
|
|
281
|
+
data.access_token,
|
|
282
|
+
data.refresh_token,
|
|
283
|
+
data.expires_in
|
|
284
|
+
);
|
|
285
|
+
return true;
|
|
286
|
+
} catch {
|
|
287
|
+
await this.clear();
|
|
288
|
+
return false;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
var auth = new AuthManager();
|
|
293
|
+
|
|
240
294
|
// src/commands/login.ts
|
|
241
295
|
var API_BASE_URL2 = process.env.WANIWANI_API_URL || "https://waniwani.com";
|
|
242
296
|
var CALLBACK_PORT = 54321;
|
|
@@ -384,7 +438,7 @@ async function exchangeCodeForToken(code, codeVerifier) {
|
|
|
384
438
|
}
|
|
385
439
|
return response.json();
|
|
386
440
|
}
|
|
387
|
-
var loginCommand = new
|
|
441
|
+
var loginCommand = new Command2("login").description("Log in to WaniWani").option("--no-browser", "Don't open the browser automatically").action(async (options, command) => {
|
|
388
442
|
const globalOptions = command.optsWithGlobals();
|
|
389
443
|
const json = globalOptions.json ?? false;
|
|
390
444
|
try {
|
|
@@ -456,30 +510,80 @@ var loginCommand = new Command("login").description("Log in to WaniWani").option
|
|
|
456
510
|
});
|
|
457
511
|
|
|
458
512
|
// src/commands/logout.ts
|
|
459
|
-
import { Command as
|
|
513
|
+
import { Command as Command3 } from "commander";
|
|
460
514
|
|
|
461
515
|
// src/lib/config.ts
|
|
462
|
-
import { access as access2, mkdir as
|
|
516
|
+
import { access as access2, mkdir as mkdir4, readFile as readFile3, writeFile as writeFile4 } from "fs/promises";
|
|
463
517
|
import { homedir as homedir2 } from "os";
|
|
464
|
-
import { join as
|
|
518
|
+
import { join as join4 } from "path";
|
|
519
|
+
import { z as z3 } from "zod";
|
|
520
|
+
|
|
521
|
+
// src/lib/project-config.ts
|
|
522
|
+
import { existsSync as existsSync2 } from "fs";
|
|
523
|
+
import { mkdir as mkdir3, readFile as readFile2, writeFile as writeFile3 } from "fs/promises";
|
|
524
|
+
import { join as join3 } from "path";
|
|
465
525
|
import { z as z2 } from "zod";
|
|
466
|
-
var
|
|
467
|
-
var
|
|
468
|
-
var
|
|
526
|
+
var PROJECT_CONFIG_DIR2 = ".waniwani";
|
|
527
|
+
var PROJECT_CONFIG_FILE2 = "settings.local.json";
|
|
528
|
+
var ProjectConfigSchema = z2.object({
|
|
529
|
+
mcpId: z2.string().optional(),
|
|
469
530
|
defaults: z2.object({
|
|
470
|
-
model: z2.string().
|
|
471
|
-
maxSteps: z2.number().
|
|
531
|
+
model: z2.string().optional(),
|
|
532
|
+
maxSteps: z2.number().optional()
|
|
533
|
+
}).optional()
|
|
534
|
+
});
|
|
535
|
+
var projectConfigCache;
|
|
536
|
+
function getProjectConfigPath() {
|
|
537
|
+
return join3(process.cwd(), PROJECT_CONFIG_DIR2, PROJECT_CONFIG_FILE2);
|
|
538
|
+
}
|
|
539
|
+
function getProjectConfigDir() {
|
|
540
|
+
return join3(process.cwd(), PROJECT_CONFIG_DIR2);
|
|
541
|
+
}
|
|
542
|
+
function hasProjectConfig() {
|
|
543
|
+
return existsSync2(getProjectConfigDir());
|
|
544
|
+
}
|
|
545
|
+
async function loadProjectConfig() {
|
|
546
|
+
if (projectConfigCache !== void 0) {
|
|
547
|
+
return projectConfigCache;
|
|
548
|
+
}
|
|
549
|
+
const configPath = getProjectConfigPath();
|
|
550
|
+
try {
|
|
551
|
+
const content = await readFile2(configPath, "utf-8");
|
|
552
|
+
projectConfigCache = ProjectConfigSchema.parse(JSON.parse(content));
|
|
553
|
+
return projectConfigCache;
|
|
554
|
+
} catch {
|
|
555
|
+
projectConfigCache = null;
|
|
556
|
+
return null;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
async function saveProjectConfig(config2) {
|
|
560
|
+
const configDir = getProjectConfigDir();
|
|
561
|
+
const configPath = getProjectConfigPath();
|
|
562
|
+
await mkdir3(configDir, { recursive: true });
|
|
563
|
+
const existing = await loadProjectConfig() ?? {};
|
|
564
|
+
const merged = ProjectConfigSchema.parse({ ...existing, ...config2 });
|
|
565
|
+
await writeFile3(configPath, JSON.stringify(merged, null, " "), "utf-8");
|
|
566
|
+
projectConfigCache = merged;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// src/lib/config.ts
|
|
570
|
+
var CONFIG_DIR2 = join4(homedir2(), ".waniwani");
|
|
571
|
+
var CONFIG_FILE = join4(CONFIG_DIR2, "config.json");
|
|
572
|
+
var ConfigSchema = z3.object({
|
|
573
|
+
defaults: z3.object({
|
|
574
|
+
model: z3.string().default("claude-sonnet-4-20250514"),
|
|
575
|
+
maxSteps: z3.number().default(10)
|
|
472
576
|
}).default(() => ({ model: "claude-sonnet-4-20250514", maxSteps: 10 })),
|
|
473
|
-
activeMcpId:
|
|
577
|
+
activeMcpId: z3.string().nullable().default(null)
|
|
474
578
|
});
|
|
475
579
|
async function ensureConfigDir2() {
|
|
476
|
-
await
|
|
580
|
+
await mkdir4(CONFIG_DIR2, { recursive: true });
|
|
477
581
|
}
|
|
478
582
|
async function readConfig() {
|
|
479
583
|
await ensureConfigDir2();
|
|
480
584
|
try {
|
|
481
585
|
await access2(CONFIG_FILE);
|
|
482
|
-
const content = await
|
|
586
|
+
const content = await readFile3(CONFIG_FILE, "utf-8");
|
|
483
587
|
return ConfigSchema.parse(JSON.parse(content));
|
|
484
588
|
} catch {
|
|
485
589
|
return ConfigSchema.parse({});
|
|
@@ -487,7 +591,7 @@ async function readConfig() {
|
|
|
487
591
|
}
|
|
488
592
|
async function writeConfig(config2) {
|
|
489
593
|
await ensureConfigDir2();
|
|
490
|
-
await
|
|
594
|
+
await writeFile4(CONFIG_FILE, JSON.stringify(config2, null, 2), "utf-8");
|
|
491
595
|
}
|
|
492
596
|
var ConfigManager = class {
|
|
493
597
|
configCache = null;
|
|
@@ -505,6 +609,21 @@ var ConfigManager = class {
|
|
|
505
609
|
const config2 = await this.getConfig();
|
|
506
610
|
return config2.defaults;
|
|
507
611
|
}
|
|
612
|
+
async getEffectiveDefaults() {
|
|
613
|
+
const globalConfig = await this.getConfig();
|
|
614
|
+
const projectConfig = await loadProjectConfig();
|
|
615
|
+
return {
|
|
616
|
+
...globalConfig.defaults,
|
|
617
|
+
...projectConfig?.defaults
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
async getEffectiveMcpId() {
|
|
621
|
+
const projectConfig = await loadProjectConfig();
|
|
622
|
+
if (projectConfig?.mcpId) {
|
|
623
|
+
return projectConfig.mcpId;
|
|
624
|
+
}
|
|
625
|
+
return this.getActiveMcpId();
|
|
626
|
+
}
|
|
508
627
|
async setDefaults(defaults) {
|
|
509
628
|
const config2 = await this.getConfig();
|
|
510
629
|
config2.defaults = { ...config2.defaults, ...defaults };
|
|
@@ -527,7 +646,7 @@ var ConfigManager = class {
|
|
|
527
646
|
var config = new ConfigManager();
|
|
528
647
|
|
|
529
648
|
// src/commands/logout.ts
|
|
530
|
-
var logoutCommand = new
|
|
649
|
+
var logoutCommand = new Command3("logout").description("Log out from WaniWani").action(async (_, command) => {
|
|
531
650
|
const globalOptions = command.optsWithGlobals();
|
|
532
651
|
const json = globalOptions.json ?? false;
|
|
533
652
|
try {
|
|
@@ -553,10 +672,10 @@ var logoutCommand = new Command2("logout").description("Log out from WaniWani").
|
|
|
553
672
|
});
|
|
554
673
|
|
|
555
674
|
// src/commands/mcp/index.ts
|
|
556
|
-
import { Command as
|
|
675
|
+
import { Command as Command11 } from "commander";
|
|
557
676
|
|
|
558
677
|
// src/commands/mcp/create.ts
|
|
559
|
-
import { Command as
|
|
678
|
+
import { Command as Command4 } from "commander";
|
|
560
679
|
import ora2 from "ora";
|
|
561
680
|
|
|
562
681
|
// src/lib/api.ts
|
|
@@ -628,7 +747,7 @@ var api = {
|
|
|
628
747
|
};
|
|
629
748
|
|
|
630
749
|
// src/commands/mcp/create.ts
|
|
631
|
-
var createCommand = new
|
|
750
|
+
var createCommand = new Command4("create").description("Create a new MCP sandbox from template").argument("<name>", "Name for the MCP project").option("--global", "Save to global config instead of project config").action(async (name, options, command) => {
|
|
632
751
|
const globalOptions = command.optsWithGlobals();
|
|
633
752
|
const json = globalOptions.json ?? false;
|
|
634
753
|
try {
|
|
@@ -637,12 +756,24 @@ var createCommand = new Command3("create").description("Create a new MCP sandbox
|
|
|
637
756
|
name
|
|
638
757
|
});
|
|
639
758
|
spinner.succeed("MCP sandbox created");
|
|
640
|
-
|
|
759
|
+
const useProjectConfig = !options.global && hasProjectConfig();
|
|
760
|
+
if (useProjectConfig) {
|
|
761
|
+
await saveProjectConfig({ mcpId: result.id });
|
|
762
|
+
} else {
|
|
763
|
+
await config.setActiveMcpId(result.id);
|
|
764
|
+
}
|
|
641
765
|
if (json) {
|
|
642
|
-
formatOutput(
|
|
766
|
+
formatOutput(
|
|
767
|
+
{ ...result, scope: useProjectConfig ? "project" : "global" },
|
|
768
|
+
true
|
|
769
|
+
);
|
|
643
770
|
} else {
|
|
771
|
+
const scope = useProjectConfig ? "(saved to project)" : "(saved globally)";
|
|
644
772
|
console.log();
|
|
645
|
-
formatSuccess(
|
|
773
|
+
formatSuccess(
|
|
774
|
+
`MCP sandbox "${name}" created successfully! ${scope}`,
|
|
775
|
+
false
|
|
776
|
+
);
|
|
646
777
|
console.log();
|
|
647
778
|
console.log(` MCP ID: ${result.id}`);
|
|
648
779
|
console.log(` Sandbox ID: ${result.sandboxId}`);
|
|
@@ -660,9 +791,9 @@ var createCommand = new Command3("create").description("Create a new MCP sandbox
|
|
|
660
791
|
});
|
|
661
792
|
|
|
662
793
|
// src/commands/mcp/deploy.ts
|
|
663
|
-
import { Command as
|
|
794
|
+
import { Command as Command5 } from "commander";
|
|
664
795
|
import ora3 from "ora";
|
|
665
|
-
var deployCommand = new
|
|
796
|
+
var deployCommand = new Command5("deploy").description("Deploy MCP server to GitHub + Vercel from sandbox").option("--repo <name>", "GitHub repository name").option("--org <name>", "GitHub organization").option("--private", "Create private repository").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
|
|
666
797
|
const globalOptions = command.optsWithGlobals();
|
|
667
798
|
const json = globalOptions.json ?? false;
|
|
668
799
|
try {
|
|
@@ -708,9 +839,9 @@ var deployCommand = new Command4("deploy").description("Deploy MCP server to Git
|
|
|
708
839
|
|
|
709
840
|
// src/commands/mcp/list.ts
|
|
710
841
|
import chalk4 from "chalk";
|
|
711
|
-
import { Command as
|
|
842
|
+
import { Command as Command6 } from "commander";
|
|
712
843
|
import ora4 from "ora";
|
|
713
|
-
var listCommand = new
|
|
844
|
+
var listCommand = new Command6("list").description("List all MCPs in your organization").option("--all", "Include stopped/expired MCPs").action(async (options, command) => {
|
|
714
845
|
const globalOptions = command.optsWithGlobals();
|
|
715
846
|
const json = globalOptions.json ?? false;
|
|
716
847
|
try {
|
|
@@ -768,9 +899,9 @@ var listCommand = new Command5("list").description("List all MCPs in your organi
|
|
|
768
899
|
|
|
769
900
|
// src/commands/mcp/status.ts
|
|
770
901
|
import chalk5 from "chalk";
|
|
771
|
-
import { Command as
|
|
902
|
+
import { Command as Command7 } from "commander";
|
|
772
903
|
import ora5 from "ora";
|
|
773
|
-
var statusCommand = new
|
|
904
|
+
var statusCommand = new Command7("status").description("Show current MCP sandbox status").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
|
|
774
905
|
const globalOptions = command.optsWithGlobals();
|
|
775
906
|
const json = globalOptions.json ?? false;
|
|
776
907
|
try {
|
|
@@ -810,9 +941,9 @@ var statusCommand = new Command6("status").description("Show current MCP sandbox
|
|
|
810
941
|
});
|
|
811
942
|
|
|
812
943
|
// src/commands/mcp/stop.ts
|
|
813
|
-
import { Command as
|
|
944
|
+
import { Command as Command8 } from "commander";
|
|
814
945
|
import ora6 from "ora";
|
|
815
|
-
var stopCommand = new
|
|
946
|
+
var stopCommand = new Command8("stop").description("Stop and clean up the MCP sandbox").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
|
|
816
947
|
const globalOptions = command.optsWithGlobals();
|
|
817
948
|
const json = globalOptions.json ?? false;
|
|
818
949
|
try {
|
|
@@ -842,9 +973,9 @@ var stopCommand = new Command7("stop").description("Stop and clean up the MCP sa
|
|
|
842
973
|
|
|
843
974
|
// src/commands/mcp/test.ts
|
|
844
975
|
import chalk6 from "chalk";
|
|
845
|
-
import { Command as
|
|
976
|
+
import { Command as Command9 } from "commander";
|
|
846
977
|
import ora7 from "ora";
|
|
847
|
-
var testCommand = new
|
|
978
|
+
var testCommand = new Command9("test").description("Test MCP tools via the sandbox").argument("[tool]", "Tool name to test (lists tools if omitted)").argument("[args...]", "JSON arguments for the tool").option("--mcp-id <id>", "Specific MCP ID").action(
|
|
848
979
|
async (tool, args, options, command) => {
|
|
849
980
|
const globalOptions = command.optsWithGlobals();
|
|
850
981
|
const json = globalOptions.json ?? false;
|
|
@@ -932,9 +1063,9 @@ Test a tool: waniwani mcp test <tool-name> '{"arg": "value"}'`
|
|
|
932
1063
|
);
|
|
933
1064
|
|
|
934
1065
|
// src/commands/mcp/use.ts
|
|
935
|
-
import { Command as
|
|
1066
|
+
import { Command as Command10 } from "commander";
|
|
936
1067
|
import ora8 from "ora";
|
|
937
|
-
var useCommand = new
|
|
1068
|
+
var useCommand = new Command10("use").description("Select an MCP to use for subsequent commands").argument("<name>", "Name of the MCP to use").option("--global", "Save to global config instead of project config").action(async (name, options, command) => {
|
|
938
1069
|
const globalOptions = command.optsWithGlobals();
|
|
939
1070
|
const json = globalOptions.json ?? false;
|
|
940
1071
|
try {
|
|
@@ -952,11 +1083,20 @@ var useCommand = new Command9("use").description("Select an MCP to use for subse
|
|
|
952
1083
|
`MCP "${name}" is ${mcp.status}. Only active MCPs can be used.`
|
|
953
1084
|
);
|
|
954
1085
|
}
|
|
955
|
-
|
|
1086
|
+
const useProjectConfig = !options.global && hasProjectConfig();
|
|
1087
|
+
if (useProjectConfig) {
|
|
1088
|
+
await saveProjectConfig({ mcpId: mcp.id });
|
|
1089
|
+
} else {
|
|
1090
|
+
await config.setActiveMcpId(mcp.id);
|
|
1091
|
+
}
|
|
956
1092
|
if (json) {
|
|
957
|
-
formatOutput(
|
|
1093
|
+
formatOutput(
|
|
1094
|
+
{ selected: mcp, scope: useProjectConfig ? "project" : "global" },
|
|
1095
|
+
true
|
|
1096
|
+
);
|
|
958
1097
|
} else {
|
|
959
|
-
|
|
1098
|
+
const scope = useProjectConfig ? "(project)" : "(global)";
|
|
1099
|
+
formatSuccess(`Now using MCP "${name}" ${scope}`, false);
|
|
960
1100
|
console.log();
|
|
961
1101
|
console.log(` MCP ID: ${mcp.id}`);
|
|
962
1102
|
console.log(` Preview URL: ${mcp.previewUrl}`);
|
|
@@ -973,16 +1113,16 @@ var useCommand = new Command9("use").description("Select an MCP to use for subse
|
|
|
973
1113
|
});
|
|
974
1114
|
|
|
975
1115
|
// src/commands/mcp/index.ts
|
|
976
|
-
var mcpCommand = new
|
|
1116
|
+
var mcpCommand = new Command11("mcp").description("MCP sandbox management commands").addCommand(createCommand).addCommand(listCommand).addCommand(useCommand).addCommand(statusCommand).addCommand(stopCommand).addCommand(testCommand).addCommand(deployCommand);
|
|
977
1117
|
|
|
978
1118
|
// src/commands/org/index.ts
|
|
979
|
-
import { Command as
|
|
1119
|
+
import { Command as Command14 } from "commander";
|
|
980
1120
|
|
|
981
1121
|
// src/commands/org/list.ts
|
|
982
1122
|
import chalk7 from "chalk";
|
|
983
|
-
import { Command as
|
|
1123
|
+
import { Command as Command12 } from "commander";
|
|
984
1124
|
import ora9 from "ora";
|
|
985
|
-
var listCommand2 = new
|
|
1125
|
+
var listCommand2 = new Command12("list").description("List your organizations").action(async (_, command) => {
|
|
986
1126
|
const globalOptions = command.optsWithGlobals();
|
|
987
1127
|
const json = globalOptions.json ?? false;
|
|
988
1128
|
try {
|
|
@@ -1032,9 +1172,9 @@ var listCommand2 = new Command11("list").description("List your organizations").
|
|
|
1032
1172
|
});
|
|
1033
1173
|
|
|
1034
1174
|
// src/commands/org/switch.ts
|
|
1035
|
-
import { Command as
|
|
1175
|
+
import { Command as Command13 } from "commander";
|
|
1036
1176
|
import ora10 from "ora";
|
|
1037
|
-
var switchCommand = new
|
|
1177
|
+
var switchCommand = new Command13("switch").description("Switch to a different organization").argument("<name>", "Name or slug of the organization to switch to").action(async (name, _, command) => {
|
|
1038
1178
|
const globalOptions = command.optsWithGlobals();
|
|
1039
1179
|
const json = globalOptions.json ?? false;
|
|
1040
1180
|
try {
|
|
@@ -1071,22 +1211,22 @@ var switchCommand = new Command12("switch").description("Switch to a different o
|
|
|
1071
1211
|
});
|
|
1072
1212
|
|
|
1073
1213
|
// src/commands/org/index.ts
|
|
1074
|
-
var orgCommand = new
|
|
1214
|
+
var orgCommand = new Command14("org").description("Organization management commands").addCommand(listCommand2).addCommand(switchCommand);
|
|
1075
1215
|
|
|
1076
1216
|
// src/commands/task.ts
|
|
1077
1217
|
import chalk8 from "chalk";
|
|
1078
|
-
import { Command as
|
|
1218
|
+
import { Command as Command15 } from "commander";
|
|
1079
1219
|
import ora11 from "ora";
|
|
1080
|
-
var taskCommand = new
|
|
1220
|
+
var taskCommand = new Command15("task").description("Send a task to Claude running in the sandbox").argument("<prompt>", "Task description/prompt").option("--mcp-id <id>", "Specific MCP ID").option("--model <model>", "Claude model to use").option("--max-steps <n>", "Maximum tool use steps").action(async (prompt, options, command) => {
|
|
1081
1221
|
const globalOptions = command.optsWithGlobals();
|
|
1082
1222
|
const json = globalOptions.json ?? false;
|
|
1083
1223
|
try {
|
|
1084
1224
|
let mcpId = options.mcpId;
|
|
1085
1225
|
if (!mcpId) {
|
|
1086
|
-
mcpId = await config.
|
|
1226
|
+
mcpId = await config.getEffectiveMcpId();
|
|
1087
1227
|
if (!mcpId) {
|
|
1088
1228
|
throw new McpError(
|
|
1089
|
-
"No active MCP. Run 'waniwani
|
|
1229
|
+
"No active MCP. Run 'waniwani init' then 'waniwani mcp use <name>'."
|
|
1090
1230
|
);
|
|
1091
1231
|
}
|
|
1092
1232
|
}
|
|
@@ -1096,7 +1236,9 @@ var taskCommand = new Command14("task").description("Send a task to Claude runni
|
|
|
1096
1236
|
"Not logged in. Run 'waniwani login' to authenticate."
|
|
1097
1237
|
);
|
|
1098
1238
|
}
|
|
1099
|
-
const
|
|
1239
|
+
const defaults = await config.getEffectiveDefaults();
|
|
1240
|
+
const model = options.model ?? defaults.model;
|
|
1241
|
+
const maxSteps = options.maxSteps ? Number.parseInt(options.maxSteps, 10) : defaults.maxSteps;
|
|
1100
1242
|
if (!json) {
|
|
1101
1243
|
console.log();
|
|
1102
1244
|
console.log(chalk8.bold("Task:"), prompt);
|
|
@@ -1113,7 +1255,7 @@ var taskCommand = new Command14("task").description("Send a task to Claude runni
|
|
|
1113
1255
|
},
|
|
1114
1256
|
body: JSON.stringify({
|
|
1115
1257
|
prompt,
|
|
1116
|
-
model
|
|
1258
|
+
model,
|
|
1117
1259
|
maxSteps
|
|
1118
1260
|
})
|
|
1119
1261
|
});
|
|
@@ -1222,9 +1364,10 @@ var taskCommand = new Command14("task").description("Send a task to Claude runni
|
|
|
1222
1364
|
|
|
1223
1365
|
// src/cli.ts
|
|
1224
1366
|
var version = "0.1.0";
|
|
1225
|
-
var program = new
|
|
1367
|
+
var program = new Command16().name("waniwani").description("WaniWani CLI for MCP development workflow").version(version).option("--json", "Output results as JSON").option("--verbose", "Enable verbose logging");
|
|
1226
1368
|
program.addCommand(loginCommand);
|
|
1227
1369
|
program.addCommand(logoutCommand);
|
|
1370
|
+
program.addCommand(initCommand);
|
|
1228
1371
|
program.addCommand(mcpCommand);
|
|
1229
1372
|
program.addCommand(taskCommand);
|
|
1230
1373
|
program.addCommand(orgCommand);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/commands/login.ts","../src/lib/auth.ts","../src/lib/errors.ts","../src/lib/output.ts","../src/commands/logout.ts","../src/lib/config.ts","../src/commands/mcp/index.ts","../src/commands/mcp/create.ts","../src/lib/api.ts","../src/commands/mcp/deploy.ts","../src/commands/mcp/list.ts","../src/commands/mcp/status.ts","../src/commands/mcp/stop.ts","../src/commands/mcp/test.ts","../src/commands/mcp/use.ts","../src/commands/org/index.ts","../src/commands/org/list.ts","../src/commands/org/switch.ts","../src/commands/task.ts","../src/index.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { loginCommand } from \"./commands/login.js\";\nimport { logoutCommand } from \"./commands/logout.js\";\nimport { mcpCommand } from \"./commands/mcp/index.js\";\nimport { orgCommand } from \"./commands/org/index.js\";\nimport { taskCommand } from \"./commands/task.js\";\n\nconst version = \"0.1.0\";\n\nexport const program = new Command()\n\t.name(\"waniwani\")\n\t.description(\"WaniWani CLI for MCP development workflow\")\n\t.version(version)\n\t.option(\"--json\", \"Output results as JSON\")\n\t.option(\"--verbose\", \"Enable verbose logging\");\n\n// Auth commands\nprogram.addCommand(loginCommand);\nprogram.addCommand(logoutCommand);\n\n// Main commands\nprogram.addCommand(mcpCommand);\nprogram.addCommand(taskCommand);\nprogram.addCommand(orgCommand);\n","import { spawn } from \"node:child_process\";\nimport { createServer, type Server } from \"node:http\";\nimport chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { auth } from \"../lib/auth.js\";\nimport { CLIError, handleError } from \"../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../lib/output.js\";\nimport type { OAuthTokenResponse } from \"../types/index.js\";\n\nconst API_BASE_URL = process.env.WANIWANI_API_URL || \"https://waniwani.com\";\nconst CALLBACK_PORT = 54321;\nconst CALLBACK_URL = `http://localhost:${CALLBACK_PORT}/callback`;\nconst CLIENT_ID = \"waniwani-cli\";\n\nfunction generateCodeVerifier(): string {\n\tconst array = new Uint8Array(32);\n\tcrypto.getRandomValues(array);\n\treturn btoa(String.fromCharCode(...array))\n\t\t.replace(/\\+/g, \"-\")\n\t\t.replace(/\\//g, \"_\")\n\t\t.replace(/=+$/, \"\");\n}\n\nasync function generateCodeChallenge(verifier: string): Promise<string> {\n\tconst encoder = new TextEncoder();\n\tconst data = encoder.encode(verifier);\n\tconst hash = await crypto.subtle.digest(\"SHA-256\", data);\n\treturn btoa(String.fromCharCode(...new Uint8Array(hash)))\n\t\t.replace(/\\+/g, \"-\")\n\t\t.replace(/\\//g, \"_\")\n\t\t.replace(/=+$/, \"\");\n}\n\nfunction generateState(): string {\n\tconst array = new Uint8Array(16);\n\tcrypto.getRandomValues(array);\n\treturn Array.from(array, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nasync function openBrowser(url: string): Promise<void> {\n\tconst [cmd, ...args] =\n\t\tprocess.platform === \"darwin\"\n\t\t\t? [\"open\", url]\n\t\t\t: process.platform === \"win32\"\n\t\t\t\t? [\"cmd\", \"/c\", \"start\", url]\n\t\t\t\t: [\"xdg-open\", url];\n\n\tspawn(cmd, args, { stdio: \"ignore\", detached: true }).unref();\n}\n\nasync function waitForCallback(\n\texpectedState: string,\n\ttimeoutMs: number = 300000,\n): Promise<string> {\n\treturn new Promise((resolve, reject) => {\n\t\tlet server: Server | null = null;\n\n\t\tconst timeout = setTimeout(() => {\n\t\t\tserver?.close();\n\t\t\treject(new CLIError(\"Login timed out\", \"LOGIN_TIMEOUT\"));\n\t\t}, timeoutMs);\n\n\t\tconst cleanup = () => {\n\t\t\tclearTimeout(timeout);\n\t\t\tserver?.close();\n\t\t};\n\n\t\tconst htmlResponse = (title: string, message: string, color: string) =>\n\t\t\t`<html>\n <body style=\"font-family: system-ui; padding: 40px; text-align: center;\">\n <h1 style=\"color: ${color};\">${title}</h1>\n <p>${message}</p>\n <p>You can close this window.</p>\n </body>\n </html>`;\n\n\t\ttry {\n\t\t\tserver = createServer((req, res) => {\n\t\t\t\tconst url = new URL(\n\t\t\t\t\treq.url || \"/\",\n\t\t\t\t\t`http://localhost:${CALLBACK_PORT}`,\n\t\t\t\t);\n\n\t\t\t\tif (url.pathname === \"/callback\") {\n\t\t\t\t\tconst code = url.searchParams.get(\"code\");\n\t\t\t\t\tconst state = url.searchParams.get(\"state\");\n\t\t\t\t\tconst error = url.searchParams.get(\"error\");\n\n\t\t\t\t\tres.setHeader(\"Content-Type\", \"text/html\");\n\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\tres.statusCode = 400;\n\t\t\t\t\t\tres.end(htmlResponse(\"Login Failed\", `Error: ${error}`, \"#ef4444\"));\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\treject(new CLIError(`OAuth error: ${error}`, \"OAUTH_ERROR\"));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (state !== expectedState) {\n\t\t\t\t\t\tres.statusCode = 400;\n\t\t\t\t\t\tres.end(\n\t\t\t\t\t\t\thtmlResponse(\n\t\t\t\t\t\t\t\t\"Login Failed\",\n\t\t\t\t\t\t\t\t\"Invalid state parameter. Please try again.\",\n\t\t\t\t\t\t\t\t\"#ef4444\",\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\treject(new CLIError(\"Invalid state parameter\", \"INVALID_STATE\"));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!code) {\n\t\t\t\t\t\tres.statusCode = 400;\n\t\t\t\t\t\tres.end(\n\t\t\t\t\t\t\thtmlResponse(\n\t\t\t\t\t\t\t\t\"Login Failed\",\n\t\t\t\t\t\t\t\t\"No authorization code received.\",\n\t\t\t\t\t\t\t\t\"#ef4444\",\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\treject(new CLIError(\"No authorization code\", \"NO_CODE\"));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tres.statusCode = 200;\n\t\t\t\t\tres.end(\n\t\t\t\t\t\thtmlResponse(\n\t\t\t\t\t\t\t\"Login Successful!\",\n\t\t\t\t\t\t\t\"You can close this window and return to the terminal.\",\n\t\t\t\t\t\t\t\"#22c55e\",\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\n\t\t\t\t\t// Schedule cleanup after response is sent\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\tresolve(code);\n\t\t\t\t\t}, 100);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tres.statusCode = 404;\n\t\t\t\tres.end(\"Not found\");\n\t\t\t});\n\n\t\t\tserver.on(\"error\", (err: NodeJS.ErrnoException) => {\n\t\t\t\tcleanup();\n\t\t\t\tif (err.code === \"EADDRINUSE\") {\n\t\t\t\t\treject(\n\t\t\t\t\t\tnew CLIError(\n\t\t\t\t\t\t\t`Port ${CALLBACK_PORT} is already in use. Close any other WaniWani CLI instances and try again.`,\n\t\t\t\t\t\t\t\"PORT_IN_USE\",\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\treject(err);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tserver.listen(CALLBACK_PORT);\n\t\t} catch (err: unknown) {\n\t\t\tcleanup();\n\t\t\treject(err);\n\t\t}\n\t});\n}\n\nasync function exchangeCodeForToken(\n\tcode: string,\n\tcodeVerifier: string,\n): Promise<OAuthTokenResponse> {\n\tconst response = await fetch(`${API_BASE_URL}/api/auth/oauth2/token`, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t},\n\t\tbody: new URLSearchParams({\n\t\t\tgrant_type: \"authorization_code\",\n\t\t\tcode,\n\t\t\tredirect_uri: CALLBACK_URL,\n\t\t\tclient_id: CLIENT_ID,\n\t\t\tcode_verifier: codeVerifier,\n\t\t}).toString(),\n\t});\n\n\tif (!response.ok) {\n\t\tconst error = await response.json().catch(() => ({}));\n\t\tthrow new CLIError(\n\t\t\t(error as { error_description?: string }).error_description ||\n\t\t\t\t\"Failed to exchange code for token\",\n\t\t\t\"TOKEN_EXCHANGE_FAILED\",\n\t\t);\n\t}\n\n\treturn response.json() as Promise<OAuthTokenResponse>;\n}\n\nexport const loginCommand = new Command(\"login\")\n\t.description(\"Log in to WaniWani\")\n\t.option(\"--no-browser\", \"Don't open the browser automatically\")\n\t.action(async (options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\t// Check if already logged in\n\t\t\tif (await auth.isLoggedIn()) {\n\t\t\t\tif (json) {\n\t\t\t\t\tformatOutput({ alreadyLoggedIn: true }, true);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\tchalk.yellow(\n\t\t\t\t\t\t\t\"Already logged in. Use 'waniwani logout' to log out first.\",\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!json) {\n\t\t\t\tconsole.log(chalk.bold(\"\\nWaniWani CLI Login\\n\"));\n\t\t\t}\n\n\t\t\t// Generate PKCE values\n\t\t\tconst codeVerifier = generateCodeVerifier();\n\t\t\tconst codeChallenge = await generateCodeChallenge(codeVerifier);\n\t\t\tconst state = generateState();\n\n\t\t\t// Build authorization URL\n\t\t\tconst authUrl = new URL(`${API_BASE_URL}/oauth/authorize`);\n\t\t\tauthUrl.searchParams.set(\"client_id\", CLIENT_ID);\n\t\t\tauthUrl.searchParams.set(\"redirect_uri\", CALLBACK_URL);\n\t\t\tauthUrl.searchParams.set(\"response_type\", \"code\");\n\t\t\tauthUrl.searchParams.set(\"code_challenge\", codeChallenge);\n\t\t\tauthUrl.searchParams.set(\"code_challenge_method\", \"S256\");\n\t\t\tauthUrl.searchParams.set(\"state\", state);\n\n\t\t\tif (!json) {\n\t\t\t\tconsole.log(\"Opening browser for authentication...\\n\");\n\t\t\t\tconsole.log(`If the browser doesn't open, visit:\\n`);\n\t\t\t\tconsole.log(chalk.cyan(` ${authUrl.toString()}`));\n\t\t\t\tconsole.log();\n\t\t\t}\n\n\t\t\t// Start callback server and open browser\n\t\t\tconst callbackPromise = waitForCallback(state);\n\n\t\t\tif (options.browser !== false) {\n\t\t\t\tawait openBrowser(authUrl.toString());\n\t\t\t}\n\n\t\t\tconst spinner = ora(\"Waiting for authorization...\").start();\n\n\t\t\t// Wait for callback with auth code\n\t\t\tconst code = await callbackPromise;\n\n\t\t\tspinner.text = \"Exchanging code for token...\";\n\n\t\t\t// Exchange code for token\n\t\t\tconst tokenResponse = await exchangeCodeForToken(code, codeVerifier);\n\n\t\t\t// Store tokens\n\t\t\tawait auth.setTokens(\n\t\t\t\ttokenResponse.access_token,\n\t\t\t\ttokenResponse.refresh_token,\n\t\t\t\ttokenResponse.expires_in,\n\t\t\t);\n\n\t\t\tspinner.succeed(\"Logged in successfully!\");\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ success: true, loggedIn: true }, true);\n\t\t\t} else {\n\t\t\t\tconsole.log();\n\t\t\t\tformatSuccess(\"You're now logged in to WaniWani!\", false);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(\"Get started:\");\n\t\t\t\tconsole.log(\n\t\t\t\t\t\" waniwani mcp create my-server Create a new MCP sandbox\",\n\t\t\t\t);\n\t\t\t\tconsole.log(' waniwani task \"Add a tool\" Send tasks to Claude');\n\t\t\t\tconsole.log(\n\t\t\t\t\t\" waniwani org list View your organizations\",\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { access, mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { z } from \"zod\";\n\nconst CONFIG_DIR = join(homedir(), \".waniwani\");\nconst AUTH_FILE = join(CONFIG_DIR, \"auth.json\");\n\nconst AuthStoreSchema = z.object({\n\taccessToken: z.string().nullable().default(null),\n\trefreshToken: z.string().nullable().default(null),\n\texpiresAt: z.string().nullable().default(null),\n});\n\ntype AuthStore = z.infer<typeof AuthStoreSchema>;\n\nconst API_BASE_URL = process.env.WANIWANI_API_URL || \"https://waniwani.com\";\n\nasync function ensureConfigDir(): Promise<void> {\n\tawait mkdir(CONFIG_DIR, { recursive: true });\n}\n\nasync function readAuthStore(): Promise<AuthStore> {\n\tawait ensureConfigDir();\n\ttry {\n\t\tawait access(AUTH_FILE);\n\t\tconst content = await readFile(AUTH_FILE, \"utf-8\");\n\t\treturn AuthStoreSchema.parse(JSON.parse(content));\n\t} catch {\n\t\treturn AuthStoreSchema.parse({});\n\t}\n}\n\nasync function writeAuthStore(store: AuthStore): Promise<void> {\n\tawait ensureConfigDir();\n\tawait writeFile(AUTH_FILE, JSON.stringify(store, null, 2), \"utf-8\");\n}\n\nclass AuthManager {\n\tprivate storeCache: AuthStore | null = null;\n\n\tprivate async getStore(): Promise<AuthStore> {\n\t\tif (!this.storeCache) {\n\t\t\tthis.storeCache = await readAuthStore();\n\t\t}\n\t\treturn this.storeCache;\n\t}\n\n\tprivate async saveStore(store: AuthStore): Promise<void> {\n\t\tthis.storeCache = store;\n\t\tawait writeAuthStore(store);\n\t}\n\n\tasync isLoggedIn(): Promise<boolean> {\n\t\tconst store = await this.getStore();\n\t\treturn !!store.accessToken;\n\t}\n\n\tasync getAccessToken(): Promise<string | null> {\n\t\tconst store = await this.getStore();\n\t\treturn store.accessToken;\n\t}\n\n\tasync getRefreshToken(): Promise<string | null> {\n\t\tconst store = await this.getStore();\n\t\treturn store.refreshToken;\n\t}\n\n\tasync setTokens(\n\t\taccessToken: string,\n\t\trefreshToken: string,\n\t\texpiresIn: number,\n\t): Promise<void> {\n\t\tconst expiresAt = new Date(Date.now() + expiresIn * 1000).toISOString();\n\t\tconst store = await this.getStore();\n\t\tstore.accessToken = accessToken;\n\t\tstore.refreshToken = refreshToken;\n\t\tstore.expiresAt = expiresAt;\n\t\tawait this.saveStore(store);\n\t}\n\n\tasync clear(): Promise<void> {\n\t\tconst emptyStore = AuthStoreSchema.parse({});\n\t\tawait this.saveStore(emptyStore);\n\t}\n\n\tasync isTokenExpired(): Promise<boolean> {\n\t\tconst store = await this.getStore();\n\t\tif (!store.expiresAt) return true;\n\t\t// Consider expired 5 minutes before actual expiry\n\t\treturn new Date(store.expiresAt).getTime() - 5 * 60 * 1000 < Date.now();\n\t}\n\n\tasync tryRefreshToken(): Promise<boolean> {\n\t\tconst refreshToken = await this.getRefreshToken();\n\t\tif (!refreshToken) return false;\n\n\t\ttry {\n\t\t\tconst response = await fetch(`${API_BASE_URL}/api/auth/oauth2/token`, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n\t\t\t\tbody: new URLSearchParams({\n\t\t\t\t\tgrant_type: \"refresh_token\",\n\t\t\t\t\trefresh_token: refreshToken,\n\t\t\t\t\tclient_id: \"waniwani-cli\",\n\t\t\t\t}).toString(),\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tawait this.clear();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst data = (await response.json()) as {\n\t\t\t\taccess_token: string;\n\t\t\t\trefresh_token: string;\n\t\t\t\texpires_in: number;\n\t\t\t};\n\n\t\t\tawait this.setTokens(\n\t\t\t\tdata.access_token,\n\t\t\t\tdata.refresh_token,\n\t\t\t\tdata.expires_in,\n\t\t\t);\n\n\t\t\treturn true;\n\t\t} catch {\n\t\t\tawait this.clear();\n\t\t\treturn false;\n\t\t}\n\t}\n}\n\nexport const auth = new AuthManager();\n","import chalk from \"chalk\";\nimport { ZodError } from \"zod\";\n\nexport class CLIError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic code: string,\n\t\tpublic details?: Record<string, unknown>,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"CLIError\";\n\t}\n}\n\nexport class ConfigError extends CLIError {\n\tconstructor(message: string, details?: Record<string, unknown>) {\n\t\tsuper(message, \"CONFIG_ERROR\", details);\n\t}\n}\n\nexport class AuthError extends CLIError {\n\tconstructor(message: string, details?: Record<string, unknown>) {\n\t\tsuper(message, \"AUTH_ERROR\", details);\n\t}\n}\n\nexport class SandboxError extends CLIError {\n\tconstructor(message: string, details?: Record<string, unknown>) {\n\t\tsuper(message, \"SANDBOX_ERROR\", details);\n\t}\n}\n\nexport class GitHubError extends CLIError {\n\tconstructor(message: string, details?: Record<string, unknown>) {\n\t\tsuper(message, \"GITHUB_ERROR\", details);\n\t}\n}\n\nexport class McpError extends CLIError {\n\tconstructor(message: string, details?: Record<string, unknown>) {\n\t\tsuper(message, \"MCP_ERROR\", details);\n\t}\n}\n\nexport function handleError(error: unknown, json: boolean): void {\n\tif (error instanceof ZodError) {\n\t\tconst message = error.issues\n\t\t\t.map((e) => `${e.path.join(\".\")}: ${e.message}`)\n\t\t\t.join(\", \");\n\t\toutputError(\"VALIDATION_ERROR\", `Invalid input: ${message}`, json);\n\t} else if (error instanceof CLIError) {\n\t\toutputError(error.code, error.message, json, error.details);\n\t} else if (error instanceof Error) {\n\t\toutputError(\"UNKNOWN_ERROR\", error.message, json);\n\t} else {\n\t\toutputError(\"UNKNOWN_ERROR\", String(error), json);\n\t}\n}\n\nfunction outputError(\n\tcode: string,\n\tmessage: string,\n\tjson: boolean,\n\tdetails?: Record<string, unknown>,\n): void {\n\tif (json) {\n\t\tconsole.error(\n\t\t\tJSON.stringify({ success: false, error: { code, message, details } }),\n\t\t);\n\t} else {\n\t\tconsole.error(chalk.red(`Error [${code}]:`), message);\n\t\tif (details) {\n\t\t\tconsole.error(chalk.gray(\"Details:\"), JSON.stringify(details, null, 2));\n\t\t}\n\t}\n}\n","import chalk from \"chalk\";\n\nexport function formatOutput<T>(data: T, json: boolean): void {\n\tif (json) {\n\t\tconsole.log(JSON.stringify({ success: true, data }, null, 2));\n\t} else {\n\t\tprettyPrint(data);\n\t}\n}\n\nexport function formatSuccess(message: string, json: boolean): void {\n\tif (json) {\n\t\tconsole.log(JSON.stringify({ success: true, message }));\n\t} else {\n\t\tconsole.log(chalk.green(\"✓\"), message);\n\t}\n}\n\nexport function formatError(error: Error | string, json: boolean): void {\n\tconst message = error instanceof Error ? error.message : error;\n\tif (json) {\n\t\tconsole.error(JSON.stringify({ success: false, error: message }));\n\t} else {\n\t\tconsole.error(chalk.red(\"✗\"), message);\n\t}\n}\n\nexport function formatTable(\n\theaders: string[],\n\trows: string[][],\n\tjson: boolean,\n): void {\n\tif (json) {\n\t\tconst data = rows.map((row) =>\n\t\t\tObject.fromEntries(headers.map((header, i) => [header, row[i]])),\n\t\t);\n\t\tconsole.log(JSON.stringify({ success: true, data }, null, 2));\n\t} else {\n\t\t// Simple table formatting without external dependency\n\t\tconst colWidths = headers.map((h, i) =>\n\t\t\tMath.max(h.length, ...rows.map((r) => (r[i] || \"\").length)),\n\t\t);\n\n\t\tconst separator = colWidths.map((w) => \"-\".repeat(w + 2)).join(\"+\");\n\t\tconst formatRow = (row: string[]) =>\n\t\t\trow.map((cell, i) => ` ${(cell || \"\").padEnd(colWidths[i])} `).join(\"|\");\n\n\t\tconsole.log(chalk.cyan(formatRow(headers)));\n\t\tconsole.log(separator);\n\t\tfor (const row of rows) {\n\t\t\tconsole.log(formatRow(row));\n\t\t}\n\t}\n}\n\nexport function formatList(\n\titems: Array<{ label: string; value: string }>,\n\tjson: boolean,\n): void {\n\tif (json) {\n\t\tconst data = Object.fromEntries(\n\t\t\titems.map((item) => [item.label, item.value]),\n\t\t);\n\t\tconsole.log(JSON.stringify({ success: true, data }, null, 2));\n\t} else {\n\t\tconst maxLabelLength = Math.max(...items.map((i) => i.label.length));\n\t\titems.forEach((item) => {\n\t\t\tconsole.log(\n\t\t\t\t`${chalk.gray(item.label.padEnd(maxLabelLength))} ${chalk.white(item.value)}`,\n\t\t\t);\n\t\t});\n\t}\n}\n\nfunction prettyPrint(data: unknown, indent = 0): void {\n\tconst prefix = \" \".repeat(indent);\n\n\tif (Array.isArray(data)) {\n\t\tdata.forEach((item, index) => {\n\t\t\tconsole.log(`${prefix}${chalk.gray(`[${index}]`)}`);\n\t\t\tprettyPrint(item, indent + 1);\n\t\t});\n\t} else if (typeof data === \"object\" && data !== null) {\n\t\tfor (const [key, value] of Object.entries(data)) {\n\t\t\tif (typeof value === \"object\" && value !== null) {\n\t\t\t\tconsole.log(`${prefix}${chalk.gray(key)}:`);\n\t\t\t\tprettyPrint(value, indent + 1);\n\t\t\t} else {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`${prefix}${chalk.gray(key)}: ${chalk.white(String(value))}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tconsole.log(`${prefix}${chalk.white(String(data))}`);\n\t}\n}\n","import { Command } from \"commander\";\nimport { auth } from \"../lib/auth.js\";\nimport { config } from \"../lib/config.js\";\nimport { handleError } from \"../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../lib/output.js\";\n\nexport const logoutCommand = new Command(\"logout\")\n\t.description(\"Log out from WaniWani\")\n\t.action(async (_, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tif (!(await auth.isLoggedIn())) {\n\t\t\t\tif (json) {\n\t\t\t\t\tformatOutput({ alreadyLoggedOut: true }, true);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(\"Not currently logged in.\");\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Clear local auth state\n\t\t\tawait auth.clear();\n\t\t\tawait config.clear();\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ success: true }, true);\n\t\t\t} else {\n\t\t\t\tformatSuccess(\"You have been logged out.\", false);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { access, mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { z } from \"zod\";\n\nconst CONFIG_DIR = join(homedir(), \".waniwani\");\nconst CONFIG_FILE = join(CONFIG_DIR, \"config.json\");\n\nconst ConfigSchema = z.object({\n\tdefaults: z\n\t\t.object({\n\t\t\tmodel: z.string().default(\"claude-sonnet-4-20250514\"),\n\t\t\tmaxSteps: z.number().default(10),\n\t\t})\n\t\t.default(() => ({ model: \"claude-sonnet-4-20250514\", maxSteps: 10 })),\n\tactiveMcpId: z.string().nullable().default(null),\n});\n\ntype Config = z.infer<typeof ConfigSchema>;\n\nasync function ensureConfigDir(): Promise<void> {\n\tawait mkdir(CONFIG_DIR, { recursive: true });\n}\n\nasync function readConfig(): Promise<Config> {\n\tawait ensureConfigDir();\n\ttry {\n\t\tawait access(CONFIG_FILE);\n\t\tconst content = await readFile(CONFIG_FILE, \"utf-8\");\n\t\treturn ConfigSchema.parse(JSON.parse(content));\n\t} catch {\n\t\treturn ConfigSchema.parse({});\n\t}\n}\n\nasync function writeConfig(config: Config): Promise<void> {\n\tawait ensureConfigDir();\n\tawait writeFile(CONFIG_FILE, JSON.stringify(config, null, 2), \"utf-8\");\n}\n\nclass ConfigManager {\n\tprivate configCache: Config | null = null;\n\n\tprivate async getConfig(): Promise<Config> {\n\t\tif (!this.configCache) {\n\t\t\tthis.configCache = await readConfig();\n\t\t}\n\t\treturn this.configCache;\n\t}\n\n\tprivate async saveConfig(config: Config): Promise<void> {\n\t\tthis.configCache = config;\n\t\tawait writeConfig(config);\n\t}\n\n\tasync getDefaults(): Promise<Config[\"defaults\"]> {\n\t\tconst config = await this.getConfig();\n\t\treturn config.defaults;\n\t}\n\n\tasync setDefaults(defaults: Partial<Config[\"defaults\"]>): Promise<void> {\n\t\tconst config = await this.getConfig();\n\t\tconfig.defaults = { ...config.defaults, ...defaults };\n\t\tawait this.saveConfig(config);\n\t}\n\n\tasync getActiveMcpId(): Promise<string | null> {\n\t\tconst config = await this.getConfig();\n\t\treturn config.activeMcpId;\n\t}\n\n\tasync setActiveMcpId(id: string | null): Promise<void> {\n\t\tconst config = await this.getConfig();\n\t\tconfig.activeMcpId = id;\n\t\tawait this.saveConfig(config);\n\t}\n\n\tasync clear(): Promise<void> {\n\t\tconst emptyConfig = ConfigSchema.parse({});\n\t\tawait this.saveConfig(emptyConfig);\n\t}\n}\n\nexport const config = new ConfigManager();\n","import { Command } from \"commander\";\nimport { createCommand } from \"./create.js\";\nimport { deployCommand } from \"./deploy.js\";\nimport { listCommand } from \"./list.js\";\nimport { statusCommand } from \"./status.js\";\nimport { stopCommand } from \"./stop.js\";\nimport { testCommand } from \"./test.js\";\nimport { useCommand } from \"./use.js\";\n\nexport const mcpCommand = new Command(\"mcp\")\n\t.description(\"MCP sandbox management commands\")\n\t.addCommand(createCommand)\n\t.addCommand(listCommand)\n\t.addCommand(useCommand)\n\t.addCommand(statusCommand)\n\t.addCommand(stopCommand)\n\t.addCommand(testCommand)\n\t.addCommand(deployCommand);\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { handleError } from \"../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\nimport type { CreateMcpResponse } from \"../../types/index.js\";\n\nexport const createCommand = new Command(\"create\")\n\t.description(\"Create a new MCP sandbox from template\")\n\t.argument(\"<name>\", \"Name for the MCP project\")\n\t.action(async (name: string, _, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst spinner = ora(\"Creating MCP sandbox...\").start();\n\n\t\t\tconst result = await api.post<CreateMcpResponse>(\"/api/admin/mcps\", {\n\t\t\t\tname,\n\t\t\t});\n\n\t\t\tspinner.succeed(\"MCP sandbox created\");\n\n\t\t\t// Set active MCP ID locally\n\t\t\tconfig.setActiveMcpId(result.id);\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(result, true);\n\t\t\t} else {\n\t\t\t\tconsole.log();\n\t\t\t\tformatSuccess(`MCP sandbox \"${name}\" created successfully!`, false);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(` MCP ID: ${result.id}`);\n\t\t\t\tconsole.log(` Sandbox ID: ${result.sandboxId}`);\n\t\t\t\tconsole.log(` Preview URL: ${result.previewUrl}`);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(`Next steps:`);\n\t\t\t\tconsole.log(` waniwani task \"Add a tool that does X\"`);\n\t\t\t\tconsole.log(` waniwani mcp test`);\n\t\t\t\tconsole.log(` waniwani mcp deploy`);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { auth } from \"./auth.js\";\nimport { AuthError, CLIError } from \"./errors.js\";\n\nconst API_BASE_URL = process.env.WANIWANI_API_URL || \"https://waniwani.com\";\n\nexport interface ApiResponse<T> {\n\tsuccess: boolean;\n\tdata?: T;\n\terror?: {\n\t\tcode: string;\n\t\tmessage: string;\n\t\tdetails?: Record<string, unknown>;\n\t};\n}\n\nexport class ApiError extends CLIError {\n\tconstructor(\n\t\tmessage: string,\n\t\tcode: string,\n\t\tpublic statusCode: number,\n\t\tdetails?: Record<string, unknown>,\n\t) {\n\t\tsuper(message, code, details);\n\t\tthis.name = \"ApiError\";\n\t}\n}\n\nasync function request<T>(\n\tmethod: string,\n\tpath: string,\n\toptions?: {\n\t\tbody?: unknown;\n\t\trequireAuth?: boolean;\n\t\theaders?: Record<string, string>;\n\t},\n): Promise<T> {\n\tconst {\n\t\tbody,\n\t\trequireAuth = true,\n\t\theaders: extraHeaders = {},\n\t} = options || {};\n\n\tconst headers: Record<string, string> = {\n\t\t\"Content-Type\": \"application/json\",\n\t\t...extraHeaders,\n\t};\n\n\tif (requireAuth) {\n\t\tconst token = await auth.getAccessToken();\n\t\tif (!token) {\n\t\t\tthrow new AuthError(\n\t\t\t\t\"Not logged in. Run 'waniwani login' to authenticate.\",\n\t\t\t);\n\t\t}\n\t\theaders.Authorization = `Bearer ${token}`;\n\t}\n\n\tconst url = `${API_BASE_URL}${path}`;\n\n\tconst response = await fetch(url, {\n\t\tmethod,\n\t\theaders,\n\t\tbody: body ? JSON.stringify(body) : undefined,\n\t});\n\n\t// Handle empty responses (204 No Content)\n\tif (response.status === 204) {\n\t\treturn undefined as T;\n\t}\n\n\tconst data = (await response.json()) as ApiResponse<T>;\n\n\tif (!response.ok || data.error) {\n\t\tconst error = data.error || {\n\t\t\tcode: \"API_ERROR\",\n\t\t\tmessage: `Request failed with status ${response.status}`,\n\t\t};\n\n\t\t// Handle token expiration\n\t\tif (response.status === 401) {\n\t\t\tconst refreshed = await auth.tryRefreshToken();\n\t\t\tif (refreshed) {\n\t\t\t\t// Retry with new token\n\t\t\t\treturn request<T>(method, path, options);\n\t\t\t}\n\t\t\tthrow new AuthError(\n\t\t\t\t\"Session expired. Run 'waniwani login' to re-authenticate.\",\n\t\t\t);\n\t\t}\n\n\t\tthrow new ApiError(\n\t\t\terror.message,\n\t\t\terror.code,\n\t\t\tresponse.status,\n\t\t\terror.details,\n\t\t);\n\t}\n\n\treturn data.data as T;\n}\n\nexport const api = {\n\tget: <T>(path: string, options?: { requireAuth?: boolean }) =>\n\t\trequest<T>(\"GET\", path, options),\n\n\tpost: <T>(\n\t\tpath: string,\n\t\tbody?: unknown,\n\t\toptions?: { requireAuth?: boolean; headers?: Record<string, string> },\n\t) => request<T>(\"POST\", path, { body, ...options }),\n\n\tdelete: <T>(path: string, options?: { requireAuth?: boolean }) =>\n\t\trequest<T>(\"DELETE\", path, options),\n\n\tgetBaseUrl: () => API_BASE_URL,\n};\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { handleError, McpError } from \"../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\nimport type { DeployResponse } from \"../../types/index.js\";\n\nexport const deployCommand = new Command(\"deploy\")\n\t.description(\"Deploy MCP server to GitHub + Vercel from sandbox\")\n\t.option(\"--repo <name>\", \"GitHub repository name\")\n\t.option(\"--org <name>\", \"GitHub organization\")\n\t.option(\"--private\", \"Create private repository\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.action(async (options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tlet mcpId = options.mcpId;\n\n\t\t\tif (!mcpId) {\n\t\t\t\tmcpId = await config.getActiveMcpId();\n\t\t\t\tif (!mcpId) {\n\t\t\t\t\tthrow new McpError(\n\t\t\t\t\t\t\"No active MCP. Run 'waniwani mcp create <name>' or 'waniwani mcp use <name>'.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst spinner = ora(\"Deploying to GitHub...\").start();\n\n\t\t\tconst result = await api.post<DeployResponse>(\n\t\t\t\t`/api/admin/mcps/${mcpId}/deploy`,\n\t\t\t\t{\n\t\t\t\t\trepoName: options.repo,\n\t\t\t\t\torg: options.org,\n\t\t\t\t\tprivate: options.private ?? false,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tspinner.succeed(\"Deployment complete!\");\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(result, true);\n\t\t\t} else {\n\t\t\t\tconsole.log();\n\t\t\t\tformatSuccess(\"MCP server deployed!\", false);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(` Repository: ${result.repository.url}`);\n\t\t\t\tif (result.deployment.url) {\n\t\t\t\t\tconsole.log(` Deployment: ${result.deployment.url}`);\n\t\t\t\t}\n\t\t\t\tconsole.log();\n\t\t\t\tif (result.deployment.note) {\n\t\t\t\t\tconsole.log(`Note: ${result.deployment.note}`);\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { handleError } from \"../../lib/errors.js\";\nimport { formatOutput, formatTable } from \"../../lib/output.js\";\nimport type { Mcp, McpListResponse } from \"../../types/index.js\";\n\nexport const listCommand = new Command(\"list\")\n\t.description(\"List all MCPs in your organization\")\n\t.option(\"--all\", \"Include stopped/expired MCPs\")\n\t.action(async (options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst spinner = ora(\"Fetching MCPs...\").start();\n\n\t\t\tconst mcps = await api.get<McpListResponse>(\n\t\t\t\t`/api/admin/mcps${options.all ? \"?all=true\" : \"\"}`,\n\t\t\t);\n\n\t\t\tspinner.stop();\n\n\t\t\tconst activeMcpId = await config.getActiveMcpId();\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(\n\t\t\t\t\t{\n\t\t\t\t\t\tmcps: mcps.map((m: Mcp) => ({\n\t\t\t\t\t\t\t...m,\n\t\t\t\t\t\t\tisActive: m.id === activeMcpId,\n\t\t\t\t\t\t})),\n\t\t\t\t\t\tactiveMcpId,\n\t\t\t\t\t},\n\t\t\t\t\ttrue,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tif (mcps.length === 0) {\n\t\t\t\t\tconsole.log(\"No MCPs found.\");\n\t\t\t\t\tconsole.log(\"\\nCreate a new MCP sandbox: waniwani mcp create <name>\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconsole.log(chalk.bold(\"\\nMCPs:\\n\"));\n\n\t\t\t\tconst rows = mcps.map((m: Mcp) => {\n\t\t\t\t\tconst isActive = m.id === activeMcpId;\n\t\t\t\t\tconst statusColor =\n\t\t\t\t\t\tm.status === \"active\"\n\t\t\t\t\t\t\t? chalk.green\n\t\t\t\t\t\t\t: m.status === \"stopped\"\n\t\t\t\t\t\t\t\t? chalk.red\n\t\t\t\t\t\t\t\t: chalk.yellow;\n\n\t\t\t\t\treturn [\n\t\t\t\t\t\tisActive\n\t\t\t\t\t\t\t? chalk.cyan(`* ${m.id.slice(0, 8)}`)\n\t\t\t\t\t\t\t: ` ${m.id.slice(0, 8)}`,\n\t\t\t\t\t\tm.name,\n\t\t\t\t\t\tstatusColor(m.status),\n\t\t\t\t\t\tm.previewUrl,\n\t\t\t\t\t\tm.createdAt ? new Date(m.createdAt).toLocaleString() : \"N/A\",\n\t\t\t\t\t];\n\t\t\t\t});\n\n\t\t\t\tformatTable(\n\t\t\t\t\t[\"ID\", \"Name\", \"Status\", \"Preview URL\", \"Created\"],\n\t\t\t\t\trows,\n\t\t\t\t\tfalse,\n\t\t\t\t);\n\n\t\t\t\tconsole.log();\n\t\t\t\tif (activeMcpId) {\n\t\t\t\t\tconsole.log(`Active MCP: ${chalk.cyan(activeMcpId.slice(0, 8))}`);\n\t\t\t\t}\n\t\t\t\tconsole.log(\"\\nSelect an MCP: waniwani mcp use <name>\");\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { handleError, McpError } from \"../../lib/errors.js\";\nimport { formatList, formatOutput } from \"../../lib/output.js\";\nimport type { Mcp } from \"../../types/index.js\";\n\nexport const statusCommand = new Command(\"status\")\n\t.description(\"Show current MCP sandbox status\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.action(async (options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tlet mcpId = options.mcpId;\n\n\t\t\tif (!mcpId) {\n\t\t\t\tmcpId = await config.getActiveMcpId();\n\t\t\t\tif (!mcpId) {\n\t\t\t\t\tthrow new McpError(\n\t\t\t\t\t\t\"No active MCP. Run 'waniwani mcp create <name>' to create one or 'waniwani mcp use <name>' to select one.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst spinner = ora(\"Fetching MCP status...\").start();\n\t\t\tconst result = await api.get<Mcp>(`/api/admin/mcps/${mcpId}`);\n\t\t\tspinner.stop();\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(result, true);\n\t\t\t} else {\n\t\t\t\tconst statusColor =\n\t\t\t\t\tresult.status === \"active\" ? chalk.green : chalk.red;\n\n\t\t\t\tformatList(\n\t\t\t\t\t[\n\t\t\t\t\t\t{ label: \"MCP ID\", value: result.id },\n\t\t\t\t\t\t{ label: \"Name\", value: result.name },\n\t\t\t\t\t\t{ label: \"Status\", value: statusColor(result.status) },\n\t\t\t\t\t\t{ label: \"Sandbox ID\", value: result.sandboxId },\n\t\t\t\t\t\t{ label: \"Preview URL\", value: result.previewUrl },\n\t\t\t\t\t\t{ label: \"Created\", value: result.createdAt },\n\t\t\t\t\t\t{ label: \"Expires\", value: result.expiresAt ?? \"N/A\" },\n\t\t\t\t\t],\n\t\t\t\t\tfalse,\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { handleError, McpError } from \"../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\n\nexport const stopCommand = new Command(\"stop\")\n\t.description(\"Stop and clean up the MCP sandbox\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.action(async (options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tlet mcpId = options.mcpId;\n\n\t\t\tif (!mcpId) {\n\t\t\t\tmcpId = await config.getActiveMcpId();\n\t\t\t\tif (!mcpId) {\n\t\t\t\t\tthrow new McpError(\"No active MCP. Use --mcp-id to specify one.\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst spinner = ora(\"Stopping MCP sandbox...\").start();\n\t\t\tawait api.delete(`/api/admin/mcps/${mcpId}`);\n\t\t\tspinner.succeed(\"MCP sandbox stopped\");\n\n\t\t\t// Clear active MCP if it was the one we stopped\n\t\t\tif ((await config.getActiveMcpId()) === mcpId) {\n\t\t\t\tawait config.setActiveMcpId(null);\n\t\t\t}\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ stopped: mcpId }, true);\n\t\t\t} else {\n\t\t\t\tformatSuccess(\"MCP sandbox stopped and cleaned up.\", false);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { handleError, McpError, SandboxError } from \"../../lib/errors.js\";\nimport { formatOutput, formatTable } from \"../../lib/output.js\";\nimport type {\n\tMcpCallResponse,\n\tMcpTestResponse,\n\tMcpToolResult,\n} from \"../../types/index.js\";\n\nexport const testCommand = new Command(\"test\")\n\t.description(\"Test MCP tools via the sandbox\")\n\t.argument(\"[tool]\", \"Tool name to test (lists tools if omitted)\")\n\t.argument(\"[args...]\", \"JSON arguments for the tool\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.action(\n\t\tasync (tool: string | undefined, args: string[], options, command) => {\n\t\t\tconst globalOptions = command.optsWithGlobals();\n\t\t\tconst json = globalOptions.json ?? false;\n\n\t\t\ttry {\n\t\t\t\tlet mcpId = options.mcpId;\n\n\t\t\t\tif (!mcpId) {\n\t\t\t\t\tmcpId = await config.getActiveMcpId();\n\t\t\t\t\tif (!mcpId) {\n\t\t\t\t\t\tthrow new McpError(\n\t\t\t\t\t\t\t\"No active MCP. Run 'waniwani mcp create <name>' or 'waniwani mcp use <name>'.\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!tool) {\n\t\t\t\t\t// List tools\n\t\t\t\t\tconst spinner = ora(\"Fetching available tools...\").start();\n\t\t\t\t\tconst result = await api.post<McpTestResponse>(\n\t\t\t\t\t\t`/api/admin/mcps/${mcpId}/test`,\n\t\t\t\t\t\t{ action: \"list\" },\n\t\t\t\t\t);\n\t\t\t\t\tspinner.stop();\n\n\t\t\t\t\tconst tools = result.tools;\n\n\t\t\t\t\tif (json) {\n\t\t\t\t\t\tformatOutput({ tools }, true);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (tools.length === 0) {\n\t\t\t\t\t\t\tconsole.log(\"No tools available.\");\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconsole.log(chalk.bold(\"\\nAvailable Tools:\\n\"));\n\t\t\t\t\t\t\tformatTable(\n\t\t\t\t\t\t\t\t[\"Name\", \"Description\"],\n\t\t\t\t\t\t\t\ttools.map((t) => [t.name, t.description || \"No description\"]),\n\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t`\\nTest a tool: waniwani mcp test <tool-name> '{\"arg\": \"value\"}'`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Call tool\n\t\t\t\t\tlet toolArgs: Record<string, unknown> = {};\n\t\t\t\t\tif (args.length > 0) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\ttoolArgs = JSON.parse(args.join(\" \"));\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tthrow new SandboxError(\n\t\t\t\t\t\t\t\t`Invalid JSON arguments. Expected format: '{\"key\": \"value\"}'`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst spinner = ora(`Calling tool \"${tool}\"...`).start();\n\t\t\t\t\tconst startTime = Date.now();\n\t\t\t\t\tconst result = await api.post<McpCallResponse>(\n\t\t\t\t\t\t`/api/admin/mcps/${mcpId}/test`,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\taction: \"call\",\n\t\t\t\t\t\t\ttool,\n\t\t\t\t\t\t\targs: toolArgs,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\tconst duration = result.duration || Date.now() - startTime;\n\t\t\t\t\tspinner.stop();\n\n\t\t\t\t\tconst output: McpToolResult = {\n\t\t\t\t\t\ttool,\n\t\t\t\t\t\tinput: toolArgs,\n\t\t\t\t\t\tresult: result.result,\n\t\t\t\t\t\tduration,\n\t\t\t\t\t};\n\n\t\t\t\t\tif (json) {\n\t\t\t\t\t\tformatOutput(output, true);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.log(chalk.bold(\"\\nTool Result:\\n\"));\n\t\t\t\t\t\tconsole.log(chalk.gray(\"Tool:\"), tool);\n\t\t\t\t\t\tconsole.log(chalk.gray(\"Input:\"), JSON.stringify(toolArgs));\n\t\t\t\t\t\tconsole.log(chalk.gray(\"Duration:\"), `${duration}ms`);\n\t\t\t\t\t\tconsole.log(chalk.gray(\"Result:\"));\n\t\t\t\t\t\tconsole.log(JSON.stringify(result.result, null, 2));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\thandleError(error, json);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t},\n\t);\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { handleError, McpError } from \"../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\nimport type { Mcp, McpListResponse } from \"../../types/index.js\";\n\nexport const useCommand = new Command(\"use\")\n\t.description(\"Select an MCP to use for subsequent commands\")\n\t.argument(\"<name>\", \"Name of the MCP to use\")\n\t.action(async (name: string, _, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst spinner = ora(\"Fetching MCPs...\").start();\n\n\t\t\t// Fetch all MCPs\n\t\t\tconst mcps = await api.get<McpListResponse>(\"/api/admin/mcps\");\n\n\t\t\tspinner.stop();\n\n\t\t\t// Find MCP by name\n\t\t\tconst mcp = mcps.find((m: Mcp) => m.name === name);\n\n\t\t\tif (!mcp) {\n\t\t\t\tthrow new McpError(\n\t\t\t\t\t`MCP \"${name}\" not found. Run 'waniwani mcp list' to see available MCPs.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (mcp.status !== \"active\") {\n\t\t\t\tthrow new McpError(\n\t\t\t\t\t`MCP \"${name}\" is ${mcp.status}. Only active MCPs can be used.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Store MCP ID locally\n\t\t\tawait config.setActiveMcpId(mcp.id);\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ selected: mcp }, true);\n\t\t\t} else {\n\t\t\t\tformatSuccess(`Now using MCP \"${name}\"`, false);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(` MCP ID: ${mcp.id}`);\n\t\t\t\tconsole.log(` Preview URL: ${mcp.previewUrl}`);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(\"Next steps:\");\n\t\t\t\tconsole.log(' waniwani task \"Add a tool\"');\n\t\t\t\tconsole.log(\" waniwani mcp test\");\n\t\t\t\tconsole.log(\" waniwani mcp status\");\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { Command } from \"commander\";\nimport { listCommand } from \"./list.js\";\nimport { switchCommand } from \"./switch.js\";\n\nexport const orgCommand = new Command(\"org\")\n\t.description(\"Organization management commands\")\n\t.addCommand(listCommand)\n\t.addCommand(switchCommand);\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { handleError } from \"../../lib/errors.js\";\nimport { formatOutput, formatTable } from \"../../lib/output.js\";\nimport type { Org, OrgListResponse } from \"../../types/index.js\";\n\nexport const listCommand = new Command(\"list\")\n\t.description(\"List your organizations\")\n\t.action(async (_, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst spinner = ora(\"Fetching organizations...\").start();\n\n\t\t\tconst result = await api.get<OrgListResponse>(\"/api/oauth/orgs\");\n\n\t\t\tspinner.stop();\n\n\t\t\tconst { orgs, activeOrgId } = result;\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(\n\t\t\t\t\t{\n\t\t\t\t\t\torgs: orgs.map((o: Org) => ({\n\t\t\t\t\t\t\t...o,\n\t\t\t\t\t\t\tisActive: o.id === activeOrgId,\n\t\t\t\t\t\t})),\n\t\t\t\t\t\tactiveOrgId,\n\t\t\t\t\t},\n\t\t\t\t\ttrue,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tif (orgs.length === 0) {\n\t\t\t\t\tconsole.log(\"No organizations found.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconsole.log(chalk.bold(\"\\nOrganizations:\\n\"));\n\n\t\t\t\tconst rows = orgs.map((o: Org) => {\n\t\t\t\t\tconst isActive = o.id === activeOrgId;\n\t\t\t\t\treturn [\n\t\t\t\t\t\tisActive ? chalk.cyan(`* ${o.name}`) : ` ${o.name}`,\n\t\t\t\t\t\to.slug,\n\t\t\t\t\t\to.role,\n\t\t\t\t\t];\n\t\t\t\t});\n\n\t\t\t\tformatTable([\"Name\", \"Slug\", \"Role\"], rows, false);\n\n\t\t\t\tconsole.log();\n\t\t\t\tif (activeOrgId) {\n\t\t\t\t\tconst activeOrg = orgs.find((o: Org) => o.id === activeOrgId);\n\t\t\t\t\tif (activeOrg) {\n\t\t\t\t\t\tconsole.log(`Active organization: ${chalk.cyan(activeOrg.name)}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconsole.log(\"\\nSwitch organization: waniwani org switch <name>\");\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { CLIError, handleError } from \"../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\nimport type {\n\tOrg,\n\tOrgListResponse,\n\tOrgSwitchResponse,\n} from \"../../types/index.js\";\n\nexport const switchCommand = new Command(\"switch\")\n\t.description(\"Switch to a different organization\")\n\t.argument(\"<name>\", \"Name or slug of the organization to switch to\")\n\t.action(async (name: string, _, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst spinner = ora(\"Fetching organizations...\").start();\n\n\t\t\t// First fetch orgs to find the org ID\n\t\t\tconst { orgs } = await api.get<OrgListResponse>(\"/api/oauth/orgs\");\n\n\t\t\t// Find org by name or slug\n\t\t\tconst org = orgs.find((o: Org) => o.name === name || o.slug === name);\n\n\t\t\tif (!org) {\n\t\t\t\tspinner.stop();\n\t\t\t\tthrow new CLIError(\n\t\t\t\t\t`Organization \"${name}\" not found. Run 'waniwani org list' to see available organizations.`,\n\t\t\t\t\t\"ORG_NOT_FOUND\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tspinner.text = \"Switching organization...\";\n\n\t\t\t// Switch to the org\n\t\t\tawait api.post<OrgSwitchResponse>(\"/api/oauth/orgs/switch\", {\n\t\t\t\torgId: org.id,\n\t\t\t});\n\n\t\t\tspinner.succeed(\"Organization switched\");\n\n\t\t\t// Clear local MCP selection since we switched orgs\n\t\t\tconfig.setActiveMcpId(null);\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ switched: org }, true);\n\t\t\t} else {\n\t\t\t\tformatSuccess(`Switched to organization \"${org.name}\"`, false);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(\"Note: Active MCP selection has been cleared.\");\n\t\t\t\tconsole.log(\n\t\t\t\t\t\"Run 'waniwani mcp list' to see MCPs in this organization.\",\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../lib/api.js\";\nimport { auth } from \"../lib/auth.js\";\nimport { config } from \"../lib/config.js\";\nimport { AuthError, handleError, McpError } from \"../lib/errors.js\";\nimport { formatOutput } from \"../lib/output.js\";\nimport type { TaskDoneEvent, TaskStep, TaskStepEvent } from \"../types/index.js\";\n\nexport const taskCommand = new Command(\"task\")\n\t.description(\"Send a task to Claude running in the sandbox\")\n\t.argument(\"<prompt>\", \"Task description/prompt\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.option(\"--model <model>\", \"Claude model to use\", \"claude-sonnet-4-20250514\")\n\t.option(\"--max-steps <n>\", \"Maximum tool use steps\", \"10\")\n\t.action(async (prompt: string, options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tlet mcpId = options.mcpId;\n\n\t\t\tif (!mcpId) {\n\t\t\t\tmcpId = await config.getActiveMcpId();\n\t\t\t\tif (!mcpId) {\n\t\t\t\t\tthrow new McpError(\n\t\t\t\t\t\t\"No active MCP. Run 'waniwani mcp create <name>' or 'waniwani mcp use <name>'.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst token = await auth.getAccessToken();\n\t\t\tif (!token) {\n\t\t\t\tthrow new AuthError(\n\t\t\t\t\t\"Not logged in. Run 'waniwani login' to authenticate.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst maxSteps = parseInt(options.maxSteps, 10);\n\n\t\t\tif (!json) {\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(chalk.bold(\"Task:\"), prompt);\n\t\t\t\tconsole.log();\n\t\t\t}\n\n\t\t\tconst spinner = ora(\"Starting task...\").start();\n\n\t\t\t// Use fetch with SSE for streaming\n\t\t\tconst baseUrl = api.getBaseUrl();\n\t\t\tconst response = await fetch(`${baseUrl}/api/admin/mcps/${mcpId}/task`, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\t\tAccept: \"text/event-stream\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tprompt,\n\t\t\t\t\tmodel: options.model,\n\t\t\t\t\tmaxSteps,\n\t\t\t\t}),\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tconst error = await response\n\t\t\t\t\t.json()\n\t\t\t\t\t.catch(() => ({ message: response.statusText }));\n\t\t\t\tspinner.fail(\"Task failed\");\n\t\t\t\tthrow new Error(\n\t\t\t\t\terror.message || `Request failed with status ${response.status}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tspinner.stop();\n\n\t\t\tconst steps: TaskStep[] = [];\n\t\t\tlet stepCount = 0;\n\t\t\tlet maxStepsReached = false;\n\n\t\t\t// Process SSE stream\n\t\t\tconst reader = response.body?.getReader();\n\t\t\tif (!reader) {\n\t\t\t\tthrow new Error(\"No response body\");\n\t\t\t}\n\n\t\t\tconst decoder = new TextDecoder();\n\t\t\tlet buffer = \"\";\n\n\t\t\twhile (true) {\n\t\t\t\tconst { done, value } = await reader.read();\n\t\t\t\tif (done) break;\n\n\t\t\t\tbuffer += decoder.decode(value, { stream: true });\n\t\t\t\tconst lines = buffer.split(\"\\n\");\n\t\t\t\tbuffer = lines.pop() || \"\";\n\n\t\t\t\tfor (const line of lines) {\n\t\t\t\t\tif (line.startsWith(\"event: \")) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (line.startsWith(\"data: \")) {\n\t\t\t\t\t\tconst data = line.slice(6);\n\t\t\t\t\t\tif (!data || data === \"[DONE]\") continue;\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst parsed = JSON.parse(data);\n\n\t\t\t\t\t\t\t// Handle step events\n\t\t\t\t\t\t\tif (parsed.type === \"text\") {\n\t\t\t\t\t\t\t\tconst event = parsed as TaskStepEvent;\n\t\t\t\t\t\t\t\tsteps.push({ type: \"text\", text: event.content });\n\t\t\t\t\t\t\t\tif (!json && event.content) {\n\t\t\t\t\t\t\t\t\tconsole.log(chalk.white(event.content));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if (parsed.type === \"tool_call\") {\n\t\t\t\t\t\t\t\tconst event = parsed as TaskStepEvent;\n\t\t\t\t\t\t\t\tsteps.push({\n\t\t\t\t\t\t\t\t\ttype: \"tool_call\",\n\t\t\t\t\t\t\t\t\ttool: event.tool,\n\t\t\t\t\t\t\t\t\tinput: event.input,\n\t\t\t\t\t\t\t\t\toutput: event.output,\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\tif (!json) {\n\t\t\t\t\t\t\t\t\tconsole.log(chalk.cyan(`> Using tool: ${event.tool}`));\n\t\t\t\t\t\t\t\t\tif (event.input?.command) {\n\t\t\t\t\t\t\t\t\t\tconsole.log(chalk.gray(` $ ${event.input.command}`));\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif (event.output) {\n\t\t\t\t\t\t\t\t\t\t// Show abbreviated output\n\t\t\t\t\t\t\t\t\t\tconst outputLines = event.output.split(\"\\n\");\n\t\t\t\t\t\t\t\t\t\tif (outputLines.length > 10) {\n\t\t\t\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\t\t\t\tchalk.gray(outputLines.slice(0, 5).join(\"\\n\")),\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\t\t\t\tchalk.gray(\n\t\t\t\t\t\t\t\t\t\t\t\t\t` ... (${outputLines.length - 10} more lines)`,\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\tconsole.log(chalk.gray(outputLines.slice(-5).join(\"\\n\")));\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tconsole.log(chalk.gray(event.output));\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tconsole.log();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if (parsed.success !== undefined) {\n\t\t\t\t\t\t\t\t// Handle done event\n\t\t\t\t\t\t\t\tconst doneEvent = parsed as TaskDoneEvent;\n\t\t\t\t\t\t\t\tstepCount = doneEvent.stepCount;\n\t\t\t\t\t\t\t\tmaxStepsReached = doneEvent.maxStepsReached || false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// Ignore malformed JSON\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst result = {\n\t\t\t\tsuccess: true,\n\t\t\t\tsteps,\n\t\t\t\tstepCount,\n\t\t\t\tmaxStepsReached,\n\t\t\t};\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(result, true);\n\t\t\t} else {\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(chalk.green(\"✓\"), `Task completed in ${stepCount} steps.`);\n\t\t\t\tif (maxStepsReached) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\tchalk.yellow(\"⚠\"),\n\t\t\t\t\t\t\"Maximum steps reached. Task may be incomplete.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { program } from \"./cli.js\";\n\nprogram.parse(process.argv);\n"],"mappings":"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","names":["Command","chalk","chalk","chalk","API_BASE_URL","chalk","Command","access","mkdir","readFile","writeFile","homedir","join","z","CONFIG_DIR","ensureConfigDir","config","Command","Command","Command","ora","API_BASE_URL","Command","ora","Command","ora","Command","ora","chalk","Command","ora","Command","ora","chalk","chalk","Command","ora","Command","ora","chalk","Command","ora","Command","ora","chalk","Command","ora","Command","ora","chalk","Command","ora","Command","ora","Command","Command","chalk","Command","ora","listCommand","Command","ora","chalk","Command","ora","Command","ora","Command","listCommand","chalk","Command","ora","Command","chalk","ora","Command"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/commands/init.ts","../src/lib/errors.ts","../src/lib/output.ts","../src/commands/login.ts","../src/lib/auth.ts","../src/commands/logout.ts","../src/lib/config.ts","../src/lib/project-config.ts","../src/commands/mcp/index.ts","../src/commands/mcp/create.ts","../src/lib/api.ts","../src/commands/mcp/deploy.ts","../src/commands/mcp/list.ts","../src/commands/mcp/status.ts","../src/commands/mcp/stop.ts","../src/commands/mcp/test.ts","../src/commands/mcp/use.ts","../src/commands/org/index.ts","../src/commands/org/list.ts","../src/commands/org/switch.ts","../src/commands/task.ts","../src/index.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { initCommand } from \"./commands/init.js\";\nimport { loginCommand } from \"./commands/login.js\";\nimport { logoutCommand } from \"./commands/logout.js\";\nimport { mcpCommand } from \"./commands/mcp/index.js\";\nimport { orgCommand } from \"./commands/org/index.js\";\nimport { taskCommand } from \"./commands/task.js\";\n\nconst version = \"0.1.0\";\n\nexport const program = new Command()\n\t.name(\"waniwani\")\n\t.description(\"WaniWani CLI for MCP development workflow\")\n\t.version(version)\n\t.option(\"--json\", \"Output results as JSON\")\n\t.option(\"--verbose\", \"Enable verbose logging\");\n\n// Auth commands\nprogram.addCommand(loginCommand);\nprogram.addCommand(logoutCommand);\n\n// Main commands\nprogram.addCommand(initCommand);\nprogram.addCommand(mcpCommand);\nprogram.addCommand(taskCommand);\nprogram.addCommand(orgCommand);\n","import { existsSync } from \"node:fs\";\nimport { mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { Command } from \"commander\";\nimport { handleError } from \"../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../lib/output.js\";\n\nconst PROJECT_CONFIG_DIR = \".waniwani\";\nconst PROJECT_CONFIG_FILE = \"settings.local.json\";\n\nexport const initCommand = new Command(\"init\")\n\t.description(\"Initialize WaniWani project config in current directory\")\n\t.action(async (_, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst cwd = process.cwd();\n\t\t\tconst configDir = join(cwd, PROJECT_CONFIG_DIR);\n\t\t\tconst configPath = join(configDir, PROJECT_CONFIG_FILE);\n\n\t\t\tif (existsSync(configDir)) {\n\t\t\t\tif (json) {\n\t\t\t\t\tformatOutput(\n\t\t\t\t\t\t{ initialized: false, message: \"Already initialized\" },\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(\"Project already initialized (.waniwani/ exists)\");\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tawait mkdir(configDir, { recursive: true });\n\n\t\t\tconst defaultConfig = {\n\t\t\t\tmcpId: null,\n\t\t\t\tdefaults: {},\n\t\t\t};\n\n\t\t\tawait writeFile(\n\t\t\t\tconfigPath,\n\t\t\t\tJSON.stringify(defaultConfig, null, \"\\t\"),\n\t\t\t\t\"utf-8\",\n\t\t\t);\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ initialized: true, path: configDir }, true);\n\t\t\t} else {\n\t\t\t\tformatSuccess(\"Initialized WaniWani project config\", false);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(` Created: ${PROJECT_CONFIG_DIR}/${PROJECT_CONFIG_FILE}`);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(\"Now run:\");\n\t\t\t\tconsole.log(' waniwani mcp create \"my-mcp\"');\n\t\t\t\tconsole.log(\" waniwani mcp use <name>\");\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import chalk from \"chalk\";\nimport { ZodError } from \"zod\";\n\nexport class CLIError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic code: string,\n\t\tpublic details?: Record<string, unknown>,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"CLIError\";\n\t}\n}\n\nexport class ConfigError extends CLIError {\n\tconstructor(message: string, details?: Record<string, unknown>) {\n\t\tsuper(message, \"CONFIG_ERROR\", details);\n\t}\n}\n\nexport class AuthError extends CLIError {\n\tconstructor(message: string, details?: Record<string, unknown>) {\n\t\tsuper(message, \"AUTH_ERROR\", details);\n\t}\n}\n\nexport class SandboxError extends CLIError {\n\tconstructor(message: string, details?: Record<string, unknown>) {\n\t\tsuper(message, \"SANDBOX_ERROR\", details);\n\t}\n}\n\nexport class GitHubError extends CLIError {\n\tconstructor(message: string, details?: Record<string, unknown>) {\n\t\tsuper(message, \"GITHUB_ERROR\", details);\n\t}\n}\n\nexport class McpError extends CLIError {\n\tconstructor(message: string, details?: Record<string, unknown>) {\n\t\tsuper(message, \"MCP_ERROR\", details);\n\t}\n}\n\nexport function handleError(error: unknown, json: boolean): void {\n\tif (error instanceof ZodError) {\n\t\tconst message = error.issues\n\t\t\t.map((e) => `${e.path.join(\".\")}: ${e.message}`)\n\t\t\t.join(\", \");\n\t\toutputError(\"VALIDATION_ERROR\", `Invalid input: ${message}`, json);\n\t} else if (error instanceof CLIError) {\n\t\toutputError(error.code, error.message, json, error.details);\n\t} else if (error instanceof Error) {\n\t\toutputError(\"UNKNOWN_ERROR\", error.message, json);\n\t} else {\n\t\toutputError(\"UNKNOWN_ERROR\", String(error), json);\n\t}\n}\n\nfunction outputError(\n\tcode: string,\n\tmessage: string,\n\tjson: boolean,\n\tdetails?: Record<string, unknown>,\n): void {\n\tif (json) {\n\t\tconsole.error(\n\t\t\tJSON.stringify({ success: false, error: { code, message, details } }),\n\t\t);\n\t} else {\n\t\tconsole.error(chalk.red(`Error [${code}]:`), message);\n\t\tif (details) {\n\t\t\tconsole.error(chalk.gray(\"Details:\"), JSON.stringify(details, null, 2));\n\t\t}\n\t}\n}\n","import chalk from \"chalk\";\n\nexport function formatOutput<T>(data: T, json: boolean): void {\n\tif (json) {\n\t\tconsole.log(JSON.stringify({ success: true, data }, null, 2));\n\t} else {\n\t\tprettyPrint(data);\n\t}\n}\n\nexport function formatSuccess(message: string, json: boolean): void {\n\tif (json) {\n\t\tconsole.log(JSON.stringify({ success: true, message }));\n\t} else {\n\t\tconsole.log(chalk.green(\"✓\"), message);\n\t}\n}\n\nexport function formatError(error: Error | string, json: boolean): void {\n\tconst message = error instanceof Error ? error.message : error;\n\tif (json) {\n\t\tconsole.error(JSON.stringify({ success: false, error: message }));\n\t} else {\n\t\tconsole.error(chalk.red(\"✗\"), message);\n\t}\n}\n\nexport function formatTable(\n\theaders: string[],\n\trows: string[][],\n\tjson: boolean,\n): void {\n\tif (json) {\n\t\tconst data = rows.map((row) =>\n\t\t\tObject.fromEntries(headers.map((header, i) => [header, row[i]])),\n\t\t);\n\t\tconsole.log(JSON.stringify({ success: true, data }, null, 2));\n\t} else {\n\t\t// Simple table formatting without external dependency\n\t\tconst colWidths = headers.map((h, i) =>\n\t\t\tMath.max(h.length, ...rows.map((r) => (r[i] || \"\").length)),\n\t\t);\n\n\t\tconst separator = colWidths.map((w) => \"-\".repeat(w + 2)).join(\"+\");\n\t\tconst formatRow = (row: string[]) =>\n\t\t\trow.map((cell, i) => ` ${(cell || \"\").padEnd(colWidths[i])} `).join(\"|\");\n\n\t\tconsole.log(chalk.cyan(formatRow(headers)));\n\t\tconsole.log(separator);\n\t\tfor (const row of rows) {\n\t\t\tconsole.log(formatRow(row));\n\t\t}\n\t}\n}\n\nexport function formatList(\n\titems: Array<{ label: string; value: string }>,\n\tjson: boolean,\n): void {\n\tif (json) {\n\t\tconst data = Object.fromEntries(\n\t\t\titems.map((item) => [item.label, item.value]),\n\t\t);\n\t\tconsole.log(JSON.stringify({ success: true, data }, null, 2));\n\t} else {\n\t\tconst maxLabelLength = Math.max(...items.map((i) => i.label.length));\n\t\titems.forEach((item) => {\n\t\t\tconsole.log(\n\t\t\t\t`${chalk.gray(item.label.padEnd(maxLabelLength))} ${chalk.white(item.value)}`,\n\t\t\t);\n\t\t});\n\t}\n}\n\nfunction prettyPrint(data: unknown, indent = 0): void {\n\tconst prefix = \" \".repeat(indent);\n\n\tif (Array.isArray(data)) {\n\t\tdata.forEach((item, index) => {\n\t\t\tconsole.log(`${prefix}${chalk.gray(`[${index}]`)}`);\n\t\t\tprettyPrint(item, indent + 1);\n\t\t});\n\t} else if (typeof data === \"object\" && data !== null) {\n\t\tfor (const [key, value] of Object.entries(data)) {\n\t\t\tif (typeof value === \"object\" && value !== null) {\n\t\t\t\tconsole.log(`${prefix}${chalk.gray(key)}:`);\n\t\t\t\tprettyPrint(value, indent + 1);\n\t\t\t} else {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`${prefix}${chalk.gray(key)}: ${chalk.white(String(value))}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tconsole.log(`${prefix}${chalk.white(String(data))}`);\n\t}\n}\n","import { spawn } from \"node:child_process\";\nimport { createServer, type Server } from \"node:http\";\nimport chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { auth } from \"../lib/auth.js\";\nimport { CLIError, handleError } from \"../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../lib/output.js\";\nimport type { OAuthTokenResponse } from \"../types/index.js\";\n\nconst API_BASE_URL = process.env.WANIWANI_API_URL || \"https://waniwani.com\";\nconst CALLBACK_PORT = 54321;\nconst CALLBACK_URL = `http://localhost:${CALLBACK_PORT}/callback`;\nconst CLIENT_ID = \"waniwani-cli\";\n\nfunction generateCodeVerifier(): string {\n\tconst array = new Uint8Array(32);\n\tcrypto.getRandomValues(array);\n\treturn btoa(String.fromCharCode(...array))\n\t\t.replace(/\\+/g, \"-\")\n\t\t.replace(/\\//g, \"_\")\n\t\t.replace(/=+$/, \"\");\n}\n\nasync function generateCodeChallenge(verifier: string): Promise<string> {\n\tconst encoder = new TextEncoder();\n\tconst data = encoder.encode(verifier);\n\tconst hash = await crypto.subtle.digest(\"SHA-256\", data);\n\treturn btoa(String.fromCharCode(...new Uint8Array(hash)))\n\t\t.replace(/\\+/g, \"-\")\n\t\t.replace(/\\//g, \"_\")\n\t\t.replace(/=+$/, \"\");\n}\n\nfunction generateState(): string {\n\tconst array = new Uint8Array(16);\n\tcrypto.getRandomValues(array);\n\treturn Array.from(array, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nasync function openBrowser(url: string): Promise<void> {\n\tconst [cmd, ...args] =\n\t\tprocess.platform === \"darwin\"\n\t\t\t? [\"open\", url]\n\t\t\t: process.platform === \"win32\"\n\t\t\t\t? [\"cmd\", \"/c\", \"start\", url]\n\t\t\t\t: [\"xdg-open\", url];\n\n\tspawn(cmd, args, { stdio: \"ignore\", detached: true }).unref();\n}\n\nasync function waitForCallback(\n\texpectedState: string,\n\ttimeoutMs: number = 300000,\n): Promise<string> {\n\treturn new Promise((resolve, reject) => {\n\t\tlet server: Server | null = null;\n\n\t\tconst timeout = setTimeout(() => {\n\t\t\tserver?.close();\n\t\t\treject(new CLIError(\"Login timed out\", \"LOGIN_TIMEOUT\"));\n\t\t}, timeoutMs);\n\n\t\tconst cleanup = () => {\n\t\t\tclearTimeout(timeout);\n\t\t\tserver?.close();\n\t\t};\n\n\t\tconst htmlResponse = (title: string, message: string, color: string) =>\n\t\t\t`<html>\n <body style=\"font-family: system-ui; padding: 40px; text-align: center;\">\n <h1 style=\"color: ${color};\">${title}</h1>\n <p>${message}</p>\n <p>You can close this window.</p>\n </body>\n </html>`;\n\n\t\ttry {\n\t\t\tserver = createServer((req, res) => {\n\t\t\t\tconst url = new URL(\n\t\t\t\t\treq.url || \"/\",\n\t\t\t\t\t`http://localhost:${CALLBACK_PORT}`,\n\t\t\t\t);\n\n\t\t\t\tif (url.pathname === \"/callback\") {\n\t\t\t\t\tconst code = url.searchParams.get(\"code\");\n\t\t\t\t\tconst state = url.searchParams.get(\"state\");\n\t\t\t\t\tconst error = url.searchParams.get(\"error\");\n\n\t\t\t\t\tres.setHeader(\"Content-Type\", \"text/html\");\n\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\tres.statusCode = 400;\n\t\t\t\t\t\tres.end(htmlResponse(\"Login Failed\", `Error: ${error}`, \"#ef4444\"));\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\treject(new CLIError(`OAuth error: ${error}`, \"OAUTH_ERROR\"));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (state !== expectedState) {\n\t\t\t\t\t\tres.statusCode = 400;\n\t\t\t\t\t\tres.end(\n\t\t\t\t\t\t\thtmlResponse(\n\t\t\t\t\t\t\t\t\"Login Failed\",\n\t\t\t\t\t\t\t\t\"Invalid state parameter. Please try again.\",\n\t\t\t\t\t\t\t\t\"#ef4444\",\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\treject(new CLIError(\"Invalid state parameter\", \"INVALID_STATE\"));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!code) {\n\t\t\t\t\t\tres.statusCode = 400;\n\t\t\t\t\t\tres.end(\n\t\t\t\t\t\t\thtmlResponse(\n\t\t\t\t\t\t\t\t\"Login Failed\",\n\t\t\t\t\t\t\t\t\"No authorization code received.\",\n\t\t\t\t\t\t\t\t\"#ef4444\",\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\treject(new CLIError(\"No authorization code\", \"NO_CODE\"));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tres.statusCode = 200;\n\t\t\t\t\tres.end(\n\t\t\t\t\t\thtmlResponse(\n\t\t\t\t\t\t\t\"Login Successful!\",\n\t\t\t\t\t\t\t\"You can close this window and return to the terminal.\",\n\t\t\t\t\t\t\t\"#22c55e\",\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\n\t\t\t\t\t// Schedule cleanup after response is sent\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\tresolve(code);\n\t\t\t\t\t}, 100);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tres.statusCode = 404;\n\t\t\t\tres.end(\"Not found\");\n\t\t\t});\n\n\t\t\tserver.on(\"error\", (err: NodeJS.ErrnoException) => {\n\t\t\t\tcleanup();\n\t\t\t\tif (err.code === \"EADDRINUSE\") {\n\t\t\t\t\treject(\n\t\t\t\t\t\tnew CLIError(\n\t\t\t\t\t\t\t`Port ${CALLBACK_PORT} is already in use. Close any other WaniWani CLI instances and try again.`,\n\t\t\t\t\t\t\t\"PORT_IN_USE\",\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\treject(err);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tserver.listen(CALLBACK_PORT);\n\t\t} catch (err: unknown) {\n\t\t\tcleanup();\n\t\t\treject(err);\n\t\t}\n\t});\n}\n\nasync function exchangeCodeForToken(\n\tcode: string,\n\tcodeVerifier: string,\n): Promise<OAuthTokenResponse> {\n\tconst response = await fetch(`${API_BASE_URL}/api/auth/oauth2/token`, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t},\n\t\tbody: new URLSearchParams({\n\t\t\tgrant_type: \"authorization_code\",\n\t\t\tcode,\n\t\t\tredirect_uri: CALLBACK_URL,\n\t\t\tclient_id: CLIENT_ID,\n\t\t\tcode_verifier: codeVerifier,\n\t\t}).toString(),\n\t});\n\n\tif (!response.ok) {\n\t\tconst error = await response.json().catch(() => ({}));\n\t\tthrow new CLIError(\n\t\t\t(error as { error_description?: string }).error_description ||\n\t\t\t\t\"Failed to exchange code for token\",\n\t\t\t\"TOKEN_EXCHANGE_FAILED\",\n\t\t);\n\t}\n\n\treturn response.json() as Promise<OAuthTokenResponse>;\n}\n\nexport const loginCommand = new Command(\"login\")\n\t.description(\"Log in to WaniWani\")\n\t.option(\"--no-browser\", \"Don't open the browser automatically\")\n\t.action(async (options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\t// Check if already logged in\n\t\t\tif (await auth.isLoggedIn()) {\n\t\t\t\tif (json) {\n\t\t\t\t\tformatOutput({ alreadyLoggedIn: true }, true);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\tchalk.yellow(\n\t\t\t\t\t\t\t\"Already logged in. Use 'waniwani logout' to log out first.\",\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!json) {\n\t\t\t\tconsole.log(chalk.bold(\"\\nWaniWani CLI Login\\n\"));\n\t\t\t}\n\n\t\t\t// Generate PKCE values\n\t\t\tconst codeVerifier = generateCodeVerifier();\n\t\t\tconst codeChallenge = await generateCodeChallenge(codeVerifier);\n\t\t\tconst state = generateState();\n\n\t\t\t// Build authorization URL\n\t\t\tconst authUrl = new URL(`${API_BASE_URL}/oauth/authorize`);\n\t\t\tauthUrl.searchParams.set(\"client_id\", CLIENT_ID);\n\t\t\tauthUrl.searchParams.set(\"redirect_uri\", CALLBACK_URL);\n\t\t\tauthUrl.searchParams.set(\"response_type\", \"code\");\n\t\t\tauthUrl.searchParams.set(\"code_challenge\", codeChallenge);\n\t\t\tauthUrl.searchParams.set(\"code_challenge_method\", \"S256\");\n\t\t\tauthUrl.searchParams.set(\"state\", state);\n\n\t\t\tif (!json) {\n\t\t\t\tconsole.log(\"Opening browser for authentication...\\n\");\n\t\t\t\tconsole.log(`If the browser doesn't open, visit:\\n`);\n\t\t\t\tconsole.log(chalk.cyan(` ${authUrl.toString()}`));\n\t\t\t\tconsole.log();\n\t\t\t}\n\n\t\t\t// Start callback server and open browser\n\t\t\tconst callbackPromise = waitForCallback(state);\n\n\t\t\tif (options.browser !== false) {\n\t\t\t\tawait openBrowser(authUrl.toString());\n\t\t\t}\n\n\t\t\tconst spinner = ora(\"Waiting for authorization...\").start();\n\n\t\t\t// Wait for callback with auth code\n\t\t\tconst code = await callbackPromise;\n\n\t\t\tspinner.text = \"Exchanging code for token...\";\n\n\t\t\t// Exchange code for token\n\t\t\tconst tokenResponse = await exchangeCodeForToken(code, codeVerifier);\n\n\t\t\t// Store tokens\n\t\t\tawait auth.setTokens(\n\t\t\t\ttokenResponse.access_token,\n\t\t\t\ttokenResponse.refresh_token,\n\t\t\t\ttokenResponse.expires_in,\n\t\t\t);\n\n\t\t\tspinner.succeed(\"Logged in successfully!\");\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ success: true, loggedIn: true }, true);\n\t\t\t} else {\n\t\t\t\tconsole.log();\n\t\t\t\tformatSuccess(\"You're now logged in to WaniWani!\", false);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(\"Get started:\");\n\t\t\t\tconsole.log(\n\t\t\t\t\t\" waniwani mcp create my-server Create a new MCP sandbox\",\n\t\t\t\t);\n\t\t\t\tconsole.log(' waniwani task \"Add a tool\" Send tasks to Claude');\n\t\t\t\tconsole.log(\n\t\t\t\t\t\" waniwani org list View your organizations\",\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { access, mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { z } from \"zod\";\n\nconst CONFIG_DIR = join(homedir(), \".waniwani\");\nconst AUTH_FILE = join(CONFIG_DIR, \"auth.json\");\n\nconst AuthStoreSchema = z.object({\n\taccessToken: z.string().nullable().default(null),\n\trefreshToken: z.string().nullable().default(null),\n\texpiresAt: z.string().nullable().default(null),\n});\n\ntype AuthStore = z.infer<typeof AuthStoreSchema>;\n\nconst API_BASE_URL = process.env.WANIWANI_API_URL || \"https://waniwani.com\";\n\nasync function ensureConfigDir(): Promise<void> {\n\tawait mkdir(CONFIG_DIR, { recursive: true });\n}\n\nasync function readAuthStore(): Promise<AuthStore> {\n\tawait ensureConfigDir();\n\ttry {\n\t\tawait access(AUTH_FILE);\n\t\tconst content = await readFile(AUTH_FILE, \"utf-8\");\n\t\treturn AuthStoreSchema.parse(JSON.parse(content));\n\t} catch {\n\t\treturn AuthStoreSchema.parse({});\n\t}\n}\n\nasync function writeAuthStore(store: AuthStore): Promise<void> {\n\tawait ensureConfigDir();\n\tawait writeFile(AUTH_FILE, JSON.stringify(store, null, 2), \"utf-8\");\n}\n\nclass AuthManager {\n\tprivate storeCache: AuthStore | null = null;\n\n\tprivate async getStore(): Promise<AuthStore> {\n\t\tif (!this.storeCache) {\n\t\t\tthis.storeCache = await readAuthStore();\n\t\t}\n\t\treturn this.storeCache;\n\t}\n\n\tprivate async saveStore(store: AuthStore): Promise<void> {\n\t\tthis.storeCache = store;\n\t\tawait writeAuthStore(store);\n\t}\n\n\tasync isLoggedIn(): Promise<boolean> {\n\t\tconst store = await this.getStore();\n\t\treturn !!store.accessToken;\n\t}\n\n\tasync getAccessToken(): Promise<string | null> {\n\t\tconst store = await this.getStore();\n\t\treturn store.accessToken;\n\t}\n\n\tasync getRefreshToken(): Promise<string | null> {\n\t\tconst store = await this.getStore();\n\t\treturn store.refreshToken;\n\t}\n\n\tasync setTokens(\n\t\taccessToken: string,\n\t\trefreshToken: string,\n\t\texpiresIn: number,\n\t): Promise<void> {\n\t\tconst expiresAt = new Date(Date.now() + expiresIn * 1000).toISOString();\n\t\tconst store = await this.getStore();\n\t\tstore.accessToken = accessToken;\n\t\tstore.refreshToken = refreshToken;\n\t\tstore.expiresAt = expiresAt;\n\t\tawait this.saveStore(store);\n\t}\n\n\tasync clear(): Promise<void> {\n\t\tconst emptyStore = AuthStoreSchema.parse({});\n\t\tawait this.saveStore(emptyStore);\n\t}\n\n\tasync isTokenExpired(): Promise<boolean> {\n\t\tconst store = await this.getStore();\n\t\tif (!store.expiresAt) return true;\n\t\t// Consider expired 5 minutes before actual expiry\n\t\treturn new Date(store.expiresAt).getTime() - 5 * 60 * 1000 < Date.now();\n\t}\n\n\tasync tryRefreshToken(): Promise<boolean> {\n\t\tconst refreshToken = await this.getRefreshToken();\n\t\tif (!refreshToken) return false;\n\n\t\ttry {\n\t\t\tconst response = await fetch(`${API_BASE_URL}/api/auth/oauth2/token`, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n\t\t\t\tbody: new URLSearchParams({\n\t\t\t\t\tgrant_type: \"refresh_token\",\n\t\t\t\t\trefresh_token: refreshToken,\n\t\t\t\t\tclient_id: \"waniwani-cli\",\n\t\t\t\t}).toString(),\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tawait this.clear();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst data = (await response.json()) as {\n\t\t\t\taccess_token: string;\n\t\t\t\trefresh_token: string;\n\t\t\t\texpires_in: number;\n\t\t\t};\n\n\t\t\tawait this.setTokens(\n\t\t\t\tdata.access_token,\n\t\t\t\tdata.refresh_token,\n\t\t\t\tdata.expires_in,\n\t\t\t);\n\n\t\t\treturn true;\n\t\t} catch {\n\t\t\tawait this.clear();\n\t\t\treturn false;\n\t\t}\n\t}\n}\n\nexport const auth = new AuthManager();\n","import { Command } from \"commander\";\nimport { auth } from \"../lib/auth.js\";\nimport { config } from \"../lib/config.js\";\nimport { handleError } from \"../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../lib/output.js\";\n\nexport const logoutCommand = new Command(\"logout\")\n\t.description(\"Log out from WaniWani\")\n\t.action(async (_, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tif (!(await auth.isLoggedIn())) {\n\t\t\t\tif (json) {\n\t\t\t\t\tformatOutput({ alreadyLoggedOut: true }, true);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(\"Not currently logged in.\");\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Clear local auth state\n\t\t\tawait auth.clear();\n\t\t\tawait config.clear();\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ success: true }, true);\n\t\t\t} else {\n\t\t\t\tformatSuccess(\"You have been logged out.\", false);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { access, mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { z } from \"zod\";\nimport { loadProjectConfig } from \"./project-config.js\";\n\nconst CONFIG_DIR = join(homedir(), \".waniwani\");\nconst CONFIG_FILE = join(CONFIG_DIR, \"config.json\");\n\nconst ConfigSchema = z.object({\n\tdefaults: z\n\t\t.object({\n\t\t\tmodel: z.string().default(\"claude-sonnet-4-20250514\"),\n\t\t\tmaxSteps: z.number().default(10),\n\t\t})\n\t\t.default(() => ({ model: \"claude-sonnet-4-20250514\", maxSteps: 10 })),\n\tactiveMcpId: z.string().nullable().default(null),\n});\n\ntype Config = z.infer<typeof ConfigSchema>;\n\nasync function ensureConfigDir(): Promise<void> {\n\tawait mkdir(CONFIG_DIR, { recursive: true });\n}\n\nasync function readConfig(): Promise<Config> {\n\tawait ensureConfigDir();\n\ttry {\n\t\tawait access(CONFIG_FILE);\n\t\tconst content = await readFile(CONFIG_FILE, \"utf-8\");\n\t\treturn ConfigSchema.parse(JSON.parse(content));\n\t} catch {\n\t\treturn ConfigSchema.parse({});\n\t}\n}\n\nasync function writeConfig(config: Config): Promise<void> {\n\tawait ensureConfigDir();\n\tawait writeFile(CONFIG_FILE, JSON.stringify(config, null, 2), \"utf-8\");\n}\n\nclass ConfigManager {\n\tprivate configCache: Config | null = null;\n\n\tprivate async getConfig(): Promise<Config> {\n\t\tif (!this.configCache) {\n\t\t\tthis.configCache = await readConfig();\n\t\t}\n\t\treturn this.configCache;\n\t}\n\n\tprivate async saveConfig(config: Config): Promise<void> {\n\t\tthis.configCache = config;\n\t\tawait writeConfig(config);\n\t}\n\n\tasync getDefaults(): Promise<Config[\"defaults\"]> {\n\t\tconst config = await this.getConfig();\n\t\treturn config.defaults;\n\t}\n\n\tasync getEffectiveDefaults(): Promise<Config[\"defaults\"]> {\n\t\tconst globalConfig = await this.getConfig();\n\t\tconst projectConfig = await loadProjectConfig();\n\n\t\treturn {\n\t\t\t...globalConfig.defaults,\n\t\t\t...projectConfig?.defaults,\n\t\t};\n\t}\n\n\tasync getEffectiveMcpId(): Promise<string | null> {\n\t\tconst projectConfig = await loadProjectConfig();\n\t\tif (projectConfig?.mcpId) {\n\t\t\treturn projectConfig.mcpId;\n\t\t}\n\t\treturn this.getActiveMcpId();\n\t}\n\n\tasync setDefaults(defaults: Partial<Config[\"defaults\"]>): Promise<void> {\n\t\tconst config = await this.getConfig();\n\t\tconfig.defaults = { ...config.defaults, ...defaults };\n\t\tawait this.saveConfig(config);\n\t}\n\n\tasync getActiveMcpId(): Promise<string | null> {\n\t\tconst config = await this.getConfig();\n\t\treturn config.activeMcpId;\n\t}\n\n\tasync setActiveMcpId(id: string | null): Promise<void> {\n\t\tconst config = await this.getConfig();\n\t\tconfig.activeMcpId = id;\n\t\tawait this.saveConfig(config);\n\t}\n\n\tasync clear(): Promise<void> {\n\t\tconst emptyConfig = ConfigSchema.parse({});\n\t\tawait this.saveConfig(emptyConfig);\n\t}\n}\n\nexport const config = new ConfigManager();\n","import { existsSync } from \"node:fs\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { z } from \"zod\";\n\nconst PROJECT_CONFIG_DIR = \".waniwani\";\nconst PROJECT_CONFIG_FILE = \"settings.local.json\";\n\nexport const ProjectConfigSchema = z.object({\n\tmcpId: z.string().optional(),\n\tdefaults: z\n\t\t.object({\n\t\t\tmodel: z.string().optional(),\n\t\t\tmaxSteps: z.number().optional(),\n\t\t})\n\t\t.optional(),\n});\n\nexport type ProjectConfig = z.infer<typeof ProjectConfigSchema>;\n\nlet projectConfigCache: ProjectConfig | null | undefined;\n\nfunction getProjectConfigPath(): string {\n\treturn join(process.cwd(), PROJECT_CONFIG_DIR, PROJECT_CONFIG_FILE);\n}\n\nfunction getProjectConfigDir(): string {\n\treturn join(process.cwd(), PROJECT_CONFIG_DIR);\n}\n\nexport function hasProjectConfig(): boolean {\n\treturn existsSync(getProjectConfigDir());\n}\n\nexport async function loadProjectConfig(): Promise<ProjectConfig | null> {\n\tif (projectConfigCache !== undefined) {\n\t\treturn projectConfigCache;\n\t}\n\n\tconst configPath = getProjectConfigPath();\n\n\ttry {\n\t\tconst content = await readFile(configPath, \"utf-8\");\n\t\tprojectConfigCache = ProjectConfigSchema.parse(JSON.parse(content));\n\t\treturn projectConfigCache;\n\t} catch {\n\t\t// Config file doesn't exist or is invalid - that's fine\n\t\tprojectConfigCache = null;\n\t\treturn null;\n\t}\n}\n\nexport async function saveProjectConfig(\n\tconfig: Partial<ProjectConfig>,\n): Promise<void> {\n\tconst configDir = getProjectConfigDir();\n\tconst configPath = getProjectConfigPath();\n\n\t// Ensure .waniwani directory exists\n\tawait mkdir(configDir, { recursive: true });\n\n\t// Merge with existing config\n\tconst existing = (await loadProjectConfig()) ?? {};\n\tconst merged = ProjectConfigSchema.parse({ ...existing, ...config });\n\n\tawait writeFile(configPath, JSON.stringify(merged, null, \"\\t\"), \"utf-8\");\n\n\t// Update cache\n\tprojectConfigCache = merged;\n}\n\nexport function clearProjectConfigCache(): void {\n\tprojectConfigCache = undefined;\n}\n","import { Command } from \"commander\";\nimport { createCommand } from \"./create.js\";\nimport { deployCommand } from \"./deploy.js\";\nimport { listCommand } from \"./list.js\";\nimport { statusCommand } from \"./status.js\";\nimport { stopCommand } from \"./stop.js\";\nimport { testCommand } from \"./test.js\";\nimport { useCommand } from \"./use.js\";\n\nexport const mcpCommand = new Command(\"mcp\")\n\t.description(\"MCP sandbox management commands\")\n\t.addCommand(createCommand)\n\t.addCommand(listCommand)\n\t.addCommand(useCommand)\n\t.addCommand(statusCommand)\n\t.addCommand(stopCommand)\n\t.addCommand(testCommand)\n\t.addCommand(deployCommand);\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { handleError } from \"../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\nimport {\n\thasProjectConfig,\n\tsaveProjectConfig,\n} from \"../../lib/project-config.js\";\nimport type { CreateMcpResponse } from \"../../types/index.js\";\n\nexport const createCommand = new Command(\"create\")\n\t.description(\"Create a new MCP sandbox from template\")\n\t.argument(\"<name>\", \"Name for the MCP project\")\n\t.option(\"--global\", \"Save to global config instead of project config\")\n\t.action(async (name: string, options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst spinner = ora(\"Creating MCP sandbox...\").start();\n\n\t\t\tconst result = await api.post<CreateMcpResponse>(\"/api/admin/mcps\", {\n\t\t\t\tname,\n\t\t\t});\n\n\t\t\tspinner.succeed(\"MCP sandbox created\");\n\n\t\t\t// Save to project config if in a project, otherwise global\n\t\t\tconst useProjectConfig = !options.global && hasProjectConfig();\n\n\t\t\tif (useProjectConfig) {\n\t\t\t\tawait saveProjectConfig({ mcpId: result.id });\n\t\t\t} else {\n\t\t\t\tawait config.setActiveMcpId(result.id);\n\t\t\t}\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(\n\t\t\t\t\t{ ...result, scope: useProjectConfig ? \"project\" : \"global\" },\n\t\t\t\t\ttrue,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tconst scope = useProjectConfig\n\t\t\t\t\t? \"(saved to project)\"\n\t\t\t\t\t: \"(saved globally)\";\n\t\t\t\tconsole.log();\n\t\t\t\tformatSuccess(\n\t\t\t\t\t`MCP sandbox \"${name}\" created successfully! ${scope}`,\n\t\t\t\t\tfalse,\n\t\t\t\t);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(` MCP ID: ${result.id}`);\n\t\t\t\tconsole.log(` Sandbox ID: ${result.sandboxId}`);\n\t\t\t\tconsole.log(` Preview URL: ${result.previewUrl}`);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(`Next steps:`);\n\t\t\t\tconsole.log(` waniwani task \"Add a tool that does X\"`);\n\t\t\t\tconsole.log(` waniwani mcp test`);\n\t\t\t\tconsole.log(` waniwani mcp deploy`);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { auth } from \"./auth.js\";\nimport { AuthError, CLIError } from \"./errors.js\";\n\nconst API_BASE_URL = process.env.WANIWANI_API_URL || \"https://waniwani.com\";\n\nexport interface ApiResponse<T> {\n\tsuccess: boolean;\n\tdata?: T;\n\terror?: {\n\t\tcode: string;\n\t\tmessage: string;\n\t\tdetails?: Record<string, unknown>;\n\t};\n}\n\nexport class ApiError extends CLIError {\n\tconstructor(\n\t\tmessage: string,\n\t\tcode: string,\n\t\tpublic statusCode: number,\n\t\tdetails?: Record<string, unknown>,\n\t) {\n\t\tsuper(message, code, details);\n\t\tthis.name = \"ApiError\";\n\t}\n}\n\nasync function request<T>(\n\tmethod: string,\n\tpath: string,\n\toptions?: {\n\t\tbody?: unknown;\n\t\trequireAuth?: boolean;\n\t\theaders?: Record<string, string>;\n\t},\n): Promise<T> {\n\tconst {\n\t\tbody,\n\t\trequireAuth = true,\n\t\theaders: extraHeaders = {},\n\t} = options || {};\n\n\tconst headers: Record<string, string> = {\n\t\t\"Content-Type\": \"application/json\",\n\t\t...extraHeaders,\n\t};\n\n\tif (requireAuth) {\n\t\tconst token = await auth.getAccessToken();\n\t\tif (!token) {\n\t\t\tthrow new AuthError(\n\t\t\t\t\"Not logged in. Run 'waniwani login' to authenticate.\",\n\t\t\t);\n\t\t}\n\t\theaders.Authorization = `Bearer ${token}`;\n\t}\n\n\tconst url = `${API_BASE_URL}${path}`;\n\n\tconst response = await fetch(url, {\n\t\tmethod,\n\t\theaders,\n\t\tbody: body ? JSON.stringify(body) : undefined,\n\t});\n\n\t// Handle empty responses (204 No Content)\n\tif (response.status === 204) {\n\t\treturn undefined as T;\n\t}\n\n\tconst data = (await response.json()) as ApiResponse<T>;\n\n\tif (!response.ok || data.error) {\n\t\tconst error = data.error || {\n\t\t\tcode: \"API_ERROR\",\n\t\t\tmessage: `Request failed with status ${response.status}`,\n\t\t};\n\n\t\t// Handle token expiration\n\t\tif (response.status === 401) {\n\t\t\tconst refreshed = await auth.tryRefreshToken();\n\t\t\tif (refreshed) {\n\t\t\t\t// Retry with new token\n\t\t\t\treturn request<T>(method, path, options);\n\t\t\t}\n\t\t\tthrow new AuthError(\n\t\t\t\t\"Session expired. Run 'waniwani login' to re-authenticate.\",\n\t\t\t);\n\t\t}\n\n\t\tthrow new ApiError(\n\t\t\terror.message,\n\t\t\terror.code,\n\t\t\tresponse.status,\n\t\t\terror.details,\n\t\t);\n\t}\n\n\treturn data.data as T;\n}\n\nexport const api = {\n\tget: <T>(path: string, options?: { requireAuth?: boolean }) =>\n\t\trequest<T>(\"GET\", path, options),\n\n\tpost: <T>(\n\t\tpath: string,\n\t\tbody?: unknown,\n\t\toptions?: { requireAuth?: boolean; headers?: Record<string, string> },\n\t) => request<T>(\"POST\", path, { body, ...options }),\n\n\tdelete: <T>(path: string, options?: { requireAuth?: boolean }) =>\n\t\trequest<T>(\"DELETE\", path, options),\n\n\tgetBaseUrl: () => API_BASE_URL,\n};\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { handleError, McpError } from \"../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\nimport type { DeployResponse } from \"../../types/index.js\";\n\nexport const deployCommand = new Command(\"deploy\")\n\t.description(\"Deploy MCP server to GitHub + Vercel from sandbox\")\n\t.option(\"--repo <name>\", \"GitHub repository name\")\n\t.option(\"--org <name>\", \"GitHub organization\")\n\t.option(\"--private\", \"Create private repository\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.action(async (options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tlet mcpId = options.mcpId;\n\n\t\t\tif (!mcpId) {\n\t\t\t\tmcpId = await config.getActiveMcpId();\n\t\t\t\tif (!mcpId) {\n\t\t\t\t\tthrow new McpError(\n\t\t\t\t\t\t\"No active MCP. Run 'waniwani mcp create <name>' or 'waniwani mcp use <name>'.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst spinner = ora(\"Deploying to GitHub...\").start();\n\n\t\t\tconst result = await api.post<DeployResponse>(\n\t\t\t\t`/api/admin/mcps/${mcpId}/deploy`,\n\t\t\t\t{\n\t\t\t\t\trepoName: options.repo,\n\t\t\t\t\torg: options.org,\n\t\t\t\t\tprivate: options.private ?? false,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tspinner.succeed(\"Deployment complete!\");\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(result, true);\n\t\t\t} else {\n\t\t\t\tconsole.log();\n\t\t\t\tformatSuccess(\"MCP server deployed!\", false);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(` Repository: ${result.repository.url}`);\n\t\t\t\tif (result.deployment.url) {\n\t\t\t\t\tconsole.log(` Deployment: ${result.deployment.url}`);\n\t\t\t\t}\n\t\t\t\tconsole.log();\n\t\t\t\tif (result.deployment.note) {\n\t\t\t\t\tconsole.log(`Note: ${result.deployment.note}`);\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { handleError } from \"../../lib/errors.js\";\nimport { formatOutput, formatTable } from \"../../lib/output.js\";\nimport type { Mcp, McpListResponse } from \"../../types/index.js\";\n\nexport const listCommand = new Command(\"list\")\n\t.description(\"List all MCPs in your organization\")\n\t.option(\"--all\", \"Include stopped/expired MCPs\")\n\t.action(async (options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst spinner = ora(\"Fetching MCPs...\").start();\n\n\t\t\tconst mcps = await api.get<McpListResponse>(\n\t\t\t\t`/api/admin/mcps${options.all ? \"?all=true\" : \"\"}`,\n\t\t\t);\n\n\t\t\tspinner.stop();\n\n\t\t\tconst activeMcpId = await config.getActiveMcpId();\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(\n\t\t\t\t\t{\n\t\t\t\t\t\tmcps: mcps.map((m: Mcp) => ({\n\t\t\t\t\t\t\t...m,\n\t\t\t\t\t\t\tisActive: m.id === activeMcpId,\n\t\t\t\t\t\t})),\n\t\t\t\t\t\tactiveMcpId,\n\t\t\t\t\t},\n\t\t\t\t\ttrue,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tif (mcps.length === 0) {\n\t\t\t\t\tconsole.log(\"No MCPs found.\");\n\t\t\t\t\tconsole.log(\"\\nCreate a new MCP sandbox: waniwani mcp create <name>\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconsole.log(chalk.bold(\"\\nMCPs:\\n\"));\n\n\t\t\t\tconst rows = mcps.map((m: Mcp) => {\n\t\t\t\t\tconst isActive = m.id === activeMcpId;\n\t\t\t\t\tconst statusColor =\n\t\t\t\t\t\tm.status === \"active\"\n\t\t\t\t\t\t\t? chalk.green\n\t\t\t\t\t\t\t: m.status === \"stopped\"\n\t\t\t\t\t\t\t\t? chalk.red\n\t\t\t\t\t\t\t\t: chalk.yellow;\n\n\t\t\t\t\treturn [\n\t\t\t\t\t\tisActive\n\t\t\t\t\t\t\t? chalk.cyan(`* ${m.id.slice(0, 8)}`)\n\t\t\t\t\t\t\t: ` ${m.id.slice(0, 8)}`,\n\t\t\t\t\t\tm.name,\n\t\t\t\t\t\tstatusColor(m.status),\n\t\t\t\t\t\tm.previewUrl,\n\t\t\t\t\t\tm.createdAt ? new Date(m.createdAt).toLocaleString() : \"N/A\",\n\t\t\t\t\t];\n\t\t\t\t});\n\n\t\t\t\tformatTable(\n\t\t\t\t\t[\"ID\", \"Name\", \"Status\", \"Preview URL\", \"Created\"],\n\t\t\t\t\trows,\n\t\t\t\t\tfalse,\n\t\t\t\t);\n\n\t\t\t\tconsole.log();\n\t\t\t\tif (activeMcpId) {\n\t\t\t\t\tconsole.log(`Active MCP: ${chalk.cyan(activeMcpId.slice(0, 8))}`);\n\t\t\t\t}\n\t\t\t\tconsole.log(\"\\nSelect an MCP: waniwani mcp use <name>\");\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { handleError, McpError } from \"../../lib/errors.js\";\nimport { formatList, formatOutput } from \"../../lib/output.js\";\nimport type { Mcp } from \"../../types/index.js\";\n\nexport const statusCommand = new Command(\"status\")\n\t.description(\"Show current MCP sandbox status\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.action(async (options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tlet mcpId = options.mcpId;\n\n\t\t\tif (!mcpId) {\n\t\t\t\tmcpId = await config.getActiveMcpId();\n\t\t\t\tif (!mcpId) {\n\t\t\t\t\tthrow new McpError(\n\t\t\t\t\t\t\"No active MCP. Run 'waniwani mcp create <name>' to create one or 'waniwani mcp use <name>' to select one.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst spinner = ora(\"Fetching MCP status...\").start();\n\t\t\tconst result = await api.get<Mcp>(`/api/admin/mcps/${mcpId}`);\n\t\t\tspinner.stop();\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(result, true);\n\t\t\t} else {\n\t\t\t\tconst statusColor =\n\t\t\t\t\tresult.status === \"active\" ? chalk.green : chalk.red;\n\n\t\t\t\tformatList(\n\t\t\t\t\t[\n\t\t\t\t\t\t{ label: \"MCP ID\", value: result.id },\n\t\t\t\t\t\t{ label: \"Name\", value: result.name },\n\t\t\t\t\t\t{ label: \"Status\", value: statusColor(result.status) },\n\t\t\t\t\t\t{ label: \"Sandbox ID\", value: result.sandboxId },\n\t\t\t\t\t\t{ label: \"Preview URL\", value: result.previewUrl },\n\t\t\t\t\t\t{ label: \"Created\", value: result.createdAt },\n\t\t\t\t\t\t{ label: \"Expires\", value: result.expiresAt ?? \"N/A\" },\n\t\t\t\t\t],\n\t\t\t\t\tfalse,\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { handleError, McpError } from \"../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\n\nexport const stopCommand = new Command(\"stop\")\n\t.description(\"Stop and clean up the MCP sandbox\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.action(async (options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tlet mcpId = options.mcpId;\n\n\t\t\tif (!mcpId) {\n\t\t\t\tmcpId = await config.getActiveMcpId();\n\t\t\t\tif (!mcpId) {\n\t\t\t\t\tthrow new McpError(\"No active MCP. Use --mcp-id to specify one.\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst spinner = ora(\"Stopping MCP sandbox...\").start();\n\t\t\tawait api.delete(`/api/admin/mcps/${mcpId}`);\n\t\t\tspinner.succeed(\"MCP sandbox stopped\");\n\n\t\t\t// Clear active MCP if it was the one we stopped\n\t\t\tif ((await config.getActiveMcpId()) === mcpId) {\n\t\t\t\tawait config.setActiveMcpId(null);\n\t\t\t}\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ stopped: mcpId }, true);\n\t\t\t} else {\n\t\t\t\tformatSuccess(\"MCP sandbox stopped and cleaned up.\", false);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { handleError, McpError, SandboxError } from \"../../lib/errors.js\";\nimport { formatOutput, formatTable } from \"../../lib/output.js\";\nimport type {\n\tMcpCallResponse,\n\tMcpTestResponse,\n\tMcpToolResult,\n} from \"../../types/index.js\";\n\nexport const testCommand = new Command(\"test\")\n\t.description(\"Test MCP tools via the sandbox\")\n\t.argument(\"[tool]\", \"Tool name to test (lists tools if omitted)\")\n\t.argument(\"[args...]\", \"JSON arguments for the tool\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.action(\n\t\tasync (tool: string | undefined, args: string[], options, command) => {\n\t\t\tconst globalOptions = command.optsWithGlobals();\n\t\t\tconst json = globalOptions.json ?? false;\n\n\t\t\ttry {\n\t\t\t\tlet mcpId = options.mcpId;\n\n\t\t\t\tif (!mcpId) {\n\t\t\t\t\tmcpId = await config.getActiveMcpId();\n\t\t\t\t\tif (!mcpId) {\n\t\t\t\t\t\tthrow new McpError(\n\t\t\t\t\t\t\t\"No active MCP. Run 'waniwani mcp create <name>' or 'waniwani mcp use <name>'.\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!tool) {\n\t\t\t\t\t// List tools\n\t\t\t\t\tconst spinner = ora(\"Fetching available tools...\").start();\n\t\t\t\t\tconst result = await api.post<McpTestResponse>(\n\t\t\t\t\t\t`/api/admin/mcps/${mcpId}/test`,\n\t\t\t\t\t\t{ action: \"list\" },\n\t\t\t\t\t);\n\t\t\t\t\tspinner.stop();\n\n\t\t\t\t\tconst tools = result.tools;\n\n\t\t\t\t\tif (json) {\n\t\t\t\t\t\tformatOutput({ tools }, true);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (tools.length === 0) {\n\t\t\t\t\t\t\tconsole.log(\"No tools available.\");\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconsole.log(chalk.bold(\"\\nAvailable Tools:\\n\"));\n\t\t\t\t\t\t\tformatTable(\n\t\t\t\t\t\t\t\t[\"Name\", \"Description\"],\n\t\t\t\t\t\t\t\ttools.map((t) => [t.name, t.description || \"No description\"]),\n\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t`\\nTest a tool: waniwani mcp test <tool-name> '{\"arg\": \"value\"}'`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Call tool\n\t\t\t\t\tlet toolArgs: Record<string, unknown> = {};\n\t\t\t\t\tif (args.length > 0) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\ttoolArgs = JSON.parse(args.join(\" \"));\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tthrow new SandboxError(\n\t\t\t\t\t\t\t\t`Invalid JSON arguments. Expected format: '{\"key\": \"value\"}'`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst spinner = ora(`Calling tool \"${tool}\"...`).start();\n\t\t\t\t\tconst startTime = Date.now();\n\t\t\t\t\tconst result = await api.post<McpCallResponse>(\n\t\t\t\t\t\t`/api/admin/mcps/${mcpId}/test`,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\taction: \"call\",\n\t\t\t\t\t\t\ttool,\n\t\t\t\t\t\t\targs: toolArgs,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\tconst duration = result.duration || Date.now() - startTime;\n\t\t\t\t\tspinner.stop();\n\n\t\t\t\t\tconst output: McpToolResult = {\n\t\t\t\t\t\ttool,\n\t\t\t\t\t\tinput: toolArgs,\n\t\t\t\t\t\tresult: result.result,\n\t\t\t\t\t\tduration,\n\t\t\t\t\t};\n\n\t\t\t\t\tif (json) {\n\t\t\t\t\t\tformatOutput(output, true);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.log(chalk.bold(\"\\nTool Result:\\n\"));\n\t\t\t\t\t\tconsole.log(chalk.gray(\"Tool:\"), tool);\n\t\t\t\t\t\tconsole.log(chalk.gray(\"Input:\"), JSON.stringify(toolArgs));\n\t\t\t\t\t\tconsole.log(chalk.gray(\"Duration:\"), `${duration}ms`);\n\t\t\t\t\t\tconsole.log(chalk.gray(\"Result:\"));\n\t\t\t\t\t\tconsole.log(JSON.stringify(result.result, null, 2));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\thandleError(error, json);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t},\n\t);\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { handleError, McpError } from \"../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\nimport {\n\thasProjectConfig,\n\tsaveProjectConfig,\n} from \"../../lib/project-config.js\";\nimport type { Mcp, McpListResponse } from \"../../types/index.js\";\n\nexport const useCommand = new Command(\"use\")\n\t.description(\"Select an MCP to use for subsequent commands\")\n\t.argument(\"<name>\", \"Name of the MCP to use\")\n\t.option(\"--global\", \"Save to global config instead of project config\")\n\t.action(async (name: string, options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst spinner = ora(\"Fetching MCPs...\").start();\n\n\t\t\t// Fetch all MCPs\n\t\t\tconst mcps = await api.get<McpListResponse>(\"/api/admin/mcps\");\n\n\t\t\tspinner.stop();\n\n\t\t\t// Find MCP by name\n\t\t\tconst mcp = mcps.find((m: Mcp) => m.name === name);\n\n\t\t\tif (!mcp) {\n\t\t\t\tthrow new McpError(\n\t\t\t\t\t`MCP \"${name}\" not found. Run 'waniwani mcp list' to see available MCPs.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (mcp.status !== \"active\") {\n\t\t\t\tthrow new McpError(\n\t\t\t\t\t`MCP \"${name}\" is ${mcp.status}. Only active MCPs can be used.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Save to project config if in a project, otherwise global\n\t\t\tconst useProjectConfig = !options.global && hasProjectConfig();\n\n\t\t\tif (useProjectConfig) {\n\t\t\t\tawait saveProjectConfig({ mcpId: mcp.id });\n\t\t\t} else {\n\t\t\t\tawait config.setActiveMcpId(mcp.id);\n\t\t\t}\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(\n\t\t\t\t\t{ selected: mcp, scope: useProjectConfig ? \"project\" : \"global\" },\n\t\t\t\t\ttrue,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tconst scope = useProjectConfig ? \"(project)\" : \"(global)\";\n\t\t\t\tformatSuccess(`Now using MCP \"${name}\" ${scope}`, false);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(` MCP ID: ${mcp.id}`);\n\t\t\t\tconsole.log(` Preview URL: ${mcp.previewUrl}`);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(\"Next steps:\");\n\t\t\t\tconsole.log(' waniwani task \"Add a tool\"');\n\t\t\t\tconsole.log(\" waniwani mcp test\");\n\t\t\t\tconsole.log(\" waniwani mcp status\");\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { Command } from \"commander\";\nimport { listCommand } from \"./list.js\";\nimport { switchCommand } from \"./switch.js\";\n\nexport const orgCommand = new Command(\"org\")\n\t.description(\"Organization management commands\")\n\t.addCommand(listCommand)\n\t.addCommand(switchCommand);\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { handleError } from \"../../lib/errors.js\";\nimport { formatOutput, formatTable } from \"../../lib/output.js\";\nimport type { Org, OrgListResponse } from \"../../types/index.js\";\n\nexport const listCommand = new Command(\"list\")\n\t.description(\"List your organizations\")\n\t.action(async (_, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst spinner = ora(\"Fetching organizations...\").start();\n\n\t\t\tconst result = await api.get<OrgListResponse>(\"/api/oauth/orgs\");\n\n\t\t\tspinner.stop();\n\n\t\t\tconst { orgs, activeOrgId } = result;\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(\n\t\t\t\t\t{\n\t\t\t\t\t\torgs: orgs.map((o: Org) => ({\n\t\t\t\t\t\t\t...o,\n\t\t\t\t\t\t\tisActive: o.id === activeOrgId,\n\t\t\t\t\t\t})),\n\t\t\t\t\t\tactiveOrgId,\n\t\t\t\t\t},\n\t\t\t\t\ttrue,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tif (orgs.length === 0) {\n\t\t\t\t\tconsole.log(\"No organizations found.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconsole.log(chalk.bold(\"\\nOrganizations:\\n\"));\n\n\t\t\t\tconst rows = orgs.map((o: Org) => {\n\t\t\t\t\tconst isActive = o.id === activeOrgId;\n\t\t\t\t\treturn [\n\t\t\t\t\t\tisActive ? chalk.cyan(`* ${o.name}`) : ` ${o.name}`,\n\t\t\t\t\t\to.slug,\n\t\t\t\t\t\to.role,\n\t\t\t\t\t];\n\t\t\t\t});\n\n\t\t\t\tformatTable([\"Name\", \"Slug\", \"Role\"], rows, false);\n\n\t\t\t\tconsole.log();\n\t\t\t\tif (activeOrgId) {\n\t\t\t\t\tconst activeOrg = orgs.find((o: Org) => o.id === activeOrgId);\n\t\t\t\t\tif (activeOrg) {\n\t\t\t\t\t\tconsole.log(`Active organization: ${chalk.cyan(activeOrg.name)}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconsole.log(\"\\nSwitch organization: waniwani org switch <name>\");\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { CLIError, handleError } from \"../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\nimport type {\n\tOrg,\n\tOrgListResponse,\n\tOrgSwitchResponse,\n} from \"../../types/index.js\";\n\nexport const switchCommand = new Command(\"switch\")\n\t.description(\"Switch to a different organization\")\n\t.argument(\"<name>\", \"Name or slug of the organization to switch to\")\n\t.action(async (name: string, _, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst spinner = ora(\"Fetching organizations...\").start();\n\n\t\t\t// First fetch orgs to find the org ID\n\t\t\tconst { orgs } = await api.get<OrgListResponse>(\"/api/oauth/orgs\");\n\n\t\t\t// Find org by name or slug\n\t\t\tconst org = orgs.find((o: Org) => o.name === name || o.slug === name);\n\n\t\t\tif (!org) {\n\t\t\t\tspinner.stop();\n\t\t\t\tthrow new CLIError(\n\t\t\t\t\t`Organization \"${name}\" not found. Run 'waniwani org list' to see available organizations.`,\n\t\t\t\t\t\"ORG_NOT_FOUND\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tspinner.text = \"Switching organization...\";\n\n\t\t\t// Switch to the org\n\t\t\tawait api.post<OrgSwitchResponse>(\"/api/oauth/orgs/switch\", {\n\t\t\t\torgId: org.id,\n\t\t\t});\n\n\t\t\tspinner.succeed(\"Organization switched\");\n\n\t\t\t// Clear local MCP selection since we switched orgs\n\t\t\tconfig.setActiveMcpId(null);\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ switched: org }, true);\n\t\t\t} else {\n\t\t\t\tformatSuccess(`Switched to organization \"${org.name}\"`, false);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(\"Note: Active MCP selection has been cleared.\");\n\t\t\t\tconsole.log(\n\t\t\t\t\t\"Run 'waniwani mcp list' to see MCPs in this organization.\",\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../lib/api.js\";\nimport { auth } from \"../lib/auth.js\";\nimport { config } from \"../lib/config.js\";\nimport { AuthError, handleError, McpError } from \"../lib/errors.js\";\nimport { formatOutput } from \"../lib/output.js\";\nimport type { TaskDoneEvent, TaskStep, TaskStepEvent } from \"../types/index.js\";\n\nexport const taskCommand = new Command(\"task\")\n\t.description(\"Send a task to Claude running in the sandbox\")\n\t.argument(\"<prompt>\", \"Task description/prompt\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.option(\"--model <model>\", \"Claude model to use\")\n\t.option(\"--max-steps <n>\", \"Maximum tool use steps\")\n\t.action(async (prompt: string, options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tlet mcpId = options.mcpId;\n\n\t\t\tif (!mcpId) {\n\t\t\t\tmcpId = await config.getEffectiveMcpId();\n\t\t\t\tif (!mcpId) {\n\t\t\t\t\tthrow new McpError(\n\t\t\t\t\t\t\"No active MCP. Run 'waniwani init' then 'waniwani mcp use <name>'.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst token = await auth.getAccessToken();\n\t\t\tif (!token) {\n\t\t\t\tthrow new AuthError(\n\t\t\t\t\t\"Not logged in. Run 'waniwani login' to authenticate.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst defaults = await config.getEffectiveDefaults();\n\t\t\tconst model = options.model ?? defaults.model;\n\t\t\tconst maxSteps = options.maxSteps\n\t\t\t\t? Number.parseInt(options.maxSteps, 10)\n\t\t\t\t: defaults.maxSteps;\n\n\t\t\tif (!json) {\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(chalk.bold(\"Task:\"), prompt);\n\t\t\t\tconsole.log();\n\t\t\t}\n\n\t\t\tconst spinner = ora(\"Starting task...\").start();\n\n\t\t\t// Use fetch with SSE for streaming\n\t\t\tconst baseUrl = api.getBaseUrl();\n\t\t\tconst response = await fetch(`${baseUrl}/api/admin/mcps/${mcpId}/task`, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\t\tAccept: \"text/event-stream\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tprompt,\n\t\t\t\t\tmodel,\n\t\t\t\t\tmaxSteps,\n\t\t\t\t}),\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tconst error = await response\n\t\t\t\t\t.json()\n\t\t\t\t\t.catch(() => ({ message: response.statusText }));\n\t\t\t\tspinner.fail(\"Task failed\");\n\t\t\t\tthrow new Error(\n\t\t\t\t\terror.message || `Request failed with status ${response.status}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tspinner.stop();\n\n\t\t\tconst steps: TaskStep[] = [];\n\t\t\tlet stepCount = 0;\n\t\t\tlet maxStepsReached = false;\n\n\t\t\t// Process SSE stream\n\t\t\tconst reader = response.body?.getReader();\n\t\t\tif (!reader) {\n\t\t\t\tthrow new Error(\"No response body\");\n\t\t\t}\n\n\t\t\tconst decoder = new TextDecoder();\n\t\t\tlet buffer = \"\";\n\n\t\t\twhile (true) {\n\t\t\t\tconst { done, value } = await reader.read();\n\t\t\t\tif (done) break;\n\n\t\t\t\tbuffer += decoder.decode(value, { stream: true });\n\t\t\t\tconst lines = buffer.split(\"\\n\");\n\t\t\t\tbuffer = lines.pop() || \"\";\n\n\t\t\t\tfor (const line of lines) {\n\t\t\t\t\tif (line.startsWith(\"event: \")) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (line.startsWith(\"data: \")) {\n\t\t\t\t\t\tconst data = line.slice(6);\n\t\t\t\t\t\tif (!data || data === \"[DONE]\") continue;\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst parsed = JSON.parse(data);\n\n\t\t\t\t\t\t\t// Handle step events\n\t\t\t\t\t\t\tif (parsed.type === \"text\") {\n\t\t\t\t\t\t\t\tconst event = parsed as TaskStepEvent;\n\t\t\t\t\t\t\t\tsteps.push({ type: \"text\", text: event.content });\n\t\t\t\t\t\t\t\tif (!json && event.content) {\n\t\t\t\t\t\t\t\t\tconsole.log(chalk.white(event.content));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if (parsed.type === \"tool_call\") {\n\t\t\t\t\t\t\t\tconst event = parsed as TaskStepEvent;\n\t\t\t\t\t\t\t\tsteps.push({\n\t\t\t\t\t\t\t\t\ttype: \"tool_call\",\n\t\t\t\t\t\t\t\t\ttool: event.tool,\n\t\t\t\t\t\t\t\t\tinput: event.input,\n\t\t\t\t\t\t\t\t\toutput: event.output,\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\tif (!json) {\n\t\t\t\t\t\t\t\t\tconsole.log(chalk.cyan(`> Using tool: ${event.tool}`));\n\t\t\t\t\t\t\t\t\tif (event.input?.command) {\n\t\t\t\t\t\t\t\t\t\tconsole.log(chalk.gray(` $ ${event.input.command}`));\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif (event.output) {\n\t\t\t\t\t\t\t\t\t\t// Show abbreviated output\n\t\t\t\t\t\t\t\t\t\tconst outputLines = event.output.split(\"\\n\");\n\t\t\t\t\t\t\t\t\t\tif (outputLines.length > 10) {\n\t\t\t\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\t\t\t\tchalk.gray(outputLines.slice(0, 5).join(\"\\n\")),\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\t\t\t\tchalk.gray(\n\t\t\t\t\t\t\t\t\t\t\t\t\t` ... (${outputLines.length - 10} more lines)`,\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\tconsole.log(chalk.gray(outputLines.slice(-5).join(\"\\n\")));\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tconsole.log(chalk.gray(event.output));\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tconsole.log();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if (parsed.success !== undefined) {\n\t\t\t\t\t\t\t\t// Handle done event\n\t\t\t\t\t\t\t\tconst doneEvent = parsed as TaskDoneEvent;\n\t\t\t\t\t\t\t\tstepCount = doneEvent.stepCount;\n\t\t\t\t\t\t\t\tmaxStepsReached = doneEvent.maxStepsReached || false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// Ignore malformed JSON\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst result = {\n\t\t\t\tsuccess: true,\n\t\t\t\tsteps,\n\t\t\t\tstepCount,\n\t\t\t\tmaxStepsReached,\n\t\t\t};\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(result, true);\n\t\t\t} else {\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(chalk.green(\"✓\"), `Task completed in ${stepCount} steps.`);\n\t\t\t\tif (maxStepsReached) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\tchalk.yellow(\"⚠\"),\n\t\t\t\t\t\t\"Maximum steps reached. Task may be incomplete.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { program } from \"./cli.js\";\n\nprogram.parse(process.argv);\n"],"mappings":";;;AAAA,SAAS,WAAAA,iBAAe;;;ACAxB,SAAS,kBAAkB;AAC3B,SAAS,OAAO,iBAAiB;AACjC,SAAS,YAAY;AACrB,SAAS,eAAe;;;ACHxB,OAAO,WAAW;AAClB,SAAS,gBAAgB;AAElB,IAAM,WAAN,cAAuB,MAAM;AAAA,EACnC,YACC,SACO,MACA,SACN;AACD,UAAM,OAAO;AAHN;AACA;AAGP,SAAK,OAAO;AAAA,EACb;AACD;AAQO,IAAM,YAAN,cAAwB,SAAS;AAAA,EACvC,YAAY,SAAiB,SAAmC;AAC/D,UAAM,SAAS,cAAc,OAAO;AAAA,EACrC;AACD;AAEO,IAAM,eAAN,cAA2B,SAAS;AAAA,EAC1C,YAAY,SAAiB,SAAmC;AAC/D,UAAM,SAAS,iBAAiB,OAAO;AAAA,EACxC;AACD;AAQO,IAAM,WAAN,cAAuB,SAAS;AAAA,EACtC,YAAY,SAAiB,SAAmC;AAC/D,UAAM,SAAS,aAAa,OAAO;AAAA,EACpC;AACD;AAEO,SAAS,YAAY,OAAgB,MAAqB;AAChE,MAAI,iBAAiB,UAAU;AAC9B,UAAM,UAAU,MAAM,OACpB,IAAI,CAAC,MAAM,GAAG,EAAE,KAAK,KAAK,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAC9C,KAAK,IAAI;AACX,gBAAY,oBAAoB,kBAAkB,OAAO,IAAI,IAAI;AAAA,EAClE,WAAW,iBAAiB,UAAU;AACrC,gBAAY,MAAM,MAAM,MAAM,SAAS,MAAM,MAAM,OAAO;AAAA,EAC3D,WAAW,iBAAiB,OAAO;AAClC,gBAAY,iBAAiB,MAAM,SAAS,IAAI;AAAA,EACjD,OAAO;AACN,gBAAY,iBAAiB,OAAO,KAAK,GAAG,IAAI;AAAA,EACjD;AACD;AAEA,SAAS,YACR,MACA,SACA,MACA,SACO;AACP,MAAI,MAAM;AACT,YAAQ;AAAA,MACP,KAAK,UAAU,EAAE,SAAS,OAAO,OAAO,EAAE,MAAM,SAAS,QAAQ,EAAE,CAAC;AAAA,IACrE;AAAA,EACD,OAAO;AACN,YAAQ,MAAM,MAAM,IAAI,UAAU,IAAI,IAAI,GAAG,OAAO;AACpD,QAAI,SAAS;AACZ,cAAQ,MAAM,MAAM,KAAK,UAAU,GAAG,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAAA,IACvE;AAAA,EACD;AACD;;;AC3EA,OAAOC,YAAW;AAEX,SAAS,aAAgB,MAAS,MAAqB;AAC7D,MAAI,MAAM;AACT,YAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC;AAAA,EAC7D,OAAO;AACN,gBAAY,IAAI;AAAA,EACjB;AACD;AAEO,SAAS,cAAc,SAAiB,MAAqB;AACnE,MAAI,MAAM;AACT,YAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC;AAAA,EACvD,OAAO;AACN,YAAQ,IAAIA,OAAM,MAAM,QAAG,GAAG,OAAO;AAAA,EACtC;AACD;AAWO,SAAS,YACf,SACA,MACA,MACO;AACP,MAAI,MAAM;AACT,UAAM,OAAO,KAAK;AAAA,MAAI,CAAC,QACtB,OAAO,YAAY,QAAQ,IAAI,CAAC,QAAQ,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC;AAAA,IAChE;AACA,YAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC;AAAA,EAC7D,OAAO;AAEN,UAAM,YAAY,QAAQ;AAAA,MAAI,CAAC,GAAG,MACjC,KAAK,IAAI,EAAE,QAAQ,GAAG,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,MAAM,CAAC;AAAA,IAC3D;AAEA,UAAM,YAAY,UAAU,IAAI,CAAC,MAAM,IAAI,OAAO,IAAI,CAAC,CAAC,EAAE,KAAK,GAAG;AAClE,UAAM,YAAY,CAAC,QAClB,IAAI,IAAI,CAAC,MAAM,MAAM,KAAK,QAAQ,IAAI,OAAO,UAAU,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,GAAG;AAExE,YAAQ,IAAIC,OAAM,KAAK,UAAU,OAAO,CAAC,CAAC;AAC1C,YAAQ,IAAI,SAAS;AACrB,eAAW,OAAO,MAAM;AACvB,cAAQ,IAAI,UAAU,GAAG,CAAC;AAAA,IAC3B;AAAA,EACD;AACD;AAEO,SAAS,WACf,OACA,MACO;AACP,MAAI,MAAM;AACT,UAAM,OAAO,OAAO;AAAA,MACnB,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,OAAO,KAAK,KAAK,CAAC;AAAA,IAC7C;AACA,YAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC;AAAA,EAC7D,OAAO;AACN,UAAM,iBAAiB,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,MAAM,MAAM,CAAC;AACnE,UAAM,QAAQ,CAAC,SAAS;AACvB,cAAQ;AAAA,QACP,GAAGA,OAAM,KAAK,KAAK,MAAM,OAAO,cAAc,CAAC,CAAC,KAAKA,OAAM,MAAM,KAAK,KAAK,CAAC;AAAA,MAC7E;AAAA,IACD,CAAC;AAAA,EACF;AACD;AAEA,SAAS,YAAY,MAAe,SAAS,GAAS;AACrD,QAAM,SAAS,KAAK,OAAO,MAAM;AAEjC,MAAI,MAAM,QAAQ,IAAI,GAAG;AACxB,SAAK,QAAQ,CAAC,MAAM,UAAU;AAC7B,cAAQ,IAAI,GAAG,MAAM,GAAGA,OAAM,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE;AAClD,kBAAY,MAAM,SAAS,CAAC;AAAA,IAC7B,CAAC;AAAA,EACF,WAAW,OAAO,SAAS,YAAY,SAAS,MAAM;AACrD,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAChD,UAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAChD,gBAAQ,IAAI,GAAG,MAAM,GAAGA,OAAM,KAAK,GAAG,CAAC,GAAG;AAC1C,oBAAY,OAAO,SAAS,CAAC;AAAA,MAC9B,OAAO;AACN,gBAAQ;AAAA,UACP,GAAG,MAAM,GAAGA,OAAM,KAAK,GAAG,CAAC,KAAKA,OAAM,MAAM,OAAO,KAAK,CAAC,CAAC;AAAA,QAC3D;AAAA,MACD;AAAA,IACD;AAAA,EACD,OAAO;AACN,YAAQ,IAAI,GAAG,MAAM,GAAGA,OAAM,MAAM,OAAO,IAAI,CAAC,CAAC,EAAE;AAAA,EACpD;AACD;;;AFzFA,IAAM,qBAAqB;AAC3B,IAAM,sBAAsB;AAErB,IAAM,cAAc,IAAI,QAAQ,MAAM,EAC3C,YAAY,yDAAyD,EACrE,OAAO,OAAO,GAAG,YAAY;AAC7B,QAAM,gBAAgB,QAAQ,gBAAgB;AAC9C,QAAM,OAAO,cAAc,QAAQ;AAEnC,MAAI;AACH,UAAM,MAAM,QAAQ,IAAI;AACxB,UAAM,YAAY,KAAK,KAAK,kBAAkB;AAC9C,UAAM,aAAa,KAAK,WAAW,mBAAmB;AAEtD,QAAI,WAAW,SAAS,GAAG;AAC1B,UAAI,MAAM;AACT;AAAA,UACC,EAAE,aAAa,OAAO,SAAS,sBAAsB;AAAA,UACrD;AAAA,QACD;AAAA,MACD,OAAO;AACN,gBAAQ,IAAI,iDAAiD;AAAA,MAC9D;AACA;AAAA,IACD;AAEA,UAAM,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;AAE1C,UAAM,gBAAgB;AAAA,MACrB,OAAO;AAAA,MACP,UAAU,CAAC;AAAA,IACZ;AAEA,UAAM;AAAA,MACL;AAAA,MACA,KAAK,UAAU,eAAe,MAAM,GAAI;AAAA,MACxC;AAAA,IACD;AAEA,QAAI,MAAM;AACT,mBAAa,EAAE,aAAa,MAAM,MAAM,UAAU,GAAG,IAAI;AAAA,IAC1D,OAAO;AACN,oBAAc,uCAAuC,KAAK;AAC1D,cAAQ,IAAI;AACZ,cAAQ,IAAI,cAAc,kBAAkB,IAAI,mBAAmB,EAAE;AACrE,cAAQ,IAAI;AACZ,cAAQ,IAAI,UAAU;AACtB,cAAQ,IAAI,gCAAgC;AAC5C,cAAQ,IAAI,2BAA2B;AAAA,IACxC;AAAA,EACD,SAAS,OAAO;AACf,gBAAY,OAAO,IAAI;AACvB,YAAQ,KAAK,CAAC;AAAA,EACf;AACD,CAAC;;;AG7DF,SAAS,aAAa;AACtB,SAAS,oBAAiC;AAC1C,OAAOC,YAAW;AAClB,SAAS,WAAAC,gBAAe;AACxB,OAAO,SAAS;;;ACJhB,SAAS,QAAQ,SAAAC,QAAO,UAAU,aAAAC,kBAAiB;AACnD,SAAS,eAAe;AACxB,SAAS,QAAAC,aAAY;AACrB,SAAS,SAAS;AAElB,IAAM,aAAaA,MAAK,QAAQ,GAAG,WAAW;AAC9C,IAAM,YAAYA,MAAK,YAAY,WAAW;AAE9C,IAAM,kBAAkB,EAAE,OAAO;AAAA,EAChC,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,IAAI;AAAA,EAC/C,cAAc,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,IAAI;AAAA,EAChD,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,IAAI;AAC9C,CAAC;AAID,IAAM,eAAe,QAAQ,IAAI,oBAAoB;AAErD,eAAe,kBAAiC;AAC/C,QAAMF,OAAM,YAAY,EAAE,WAAW,KAAK,CAAC;AAC5C;AAEA,eAAe,gBAAoC;AAClD,QAAM,gBAAgB;AACtB,MAAI;AACH,UAAM,OAAO,SAAS;AACtB,UAAM,UAAU,MAAM,SAAS,WAAW,OAAO;AACjD,WAAO,gBAAgB,MAAM,KAAK,MAAM,OAAO,CAAC;AAAA,EACjD,QAAQ;AACP,WAAO,gBAAgB,MAAM,CAAC,CAAC;AAAA,EAChC;AACD;AAEA,eAAe,eAAe,OAAiC;AAC9D,QAAM,gBAAgB;AACtB,QAAMC,WAAU,WAAW,KAAK,UAAU,OAAO,MAAM,CAAC,GAAG,OAAO;AACnE;AAEA,IAAM,cAAN,MAAkB;AAAA,EACT,aAA+B;AAAA,EAEvC,MAAc,WAA+B;AAC5C,QAAI,CAAC,KAAK,YAAY;AACrB,WAAK,aAAa,MAAM,cAAc;AAAA,IACvC;AACA,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,MAAc,UAAU,OAAiC;AACxD,SAAK,aAAa;AAClB,UAAM,eAAe,KAAK;AAAA,EAC3B;AAAA,EAEA,MAAM,aAA+B;AACpC,UAAM,QAAQ,MAAM,KAAK,SAAS;AAClC,WAAO,CAAC,CAAC,MAAM;AAAA,EAChB;AAAA,EAEA,MAAM,iBAAyC;AAC9C,UAAM,QAAQ,MAAM,KAAK,SAAS;AAClC,WAAO,MAAM;AAAA,EACd;AAAA,EAEA,MAAM,kBAA0C;AAC/C,UAAM,QAAQ,MAAM,KAAK,SAAS;AAClC,WAAO,MAAM;AAAA,EACd;AAAA,EAEA,MAAM,UACL,aACA,cACA,WACgB;AAChB,UAAM,YAAY,IAAI,KAAK,KAAK,IAAI,IAAI,YAAY,GAAI,EAAE,YAAY;AACtE,UAAM,QAAQ,MAAM,KAAK,SAAS;AAClC,UAAM,cAAc;AACpB,UAAM,eAAe;AACrB,UAAM,YAAY;AAClB,UAAM,KAAK,UAAU,KAAK;AAAA,EAC3B;AAAA,EAEA,MAAM,QAAuB;AAC5B,UAAM,aAAa,gBAAgB,MAAM,CAAC,CAAC;AAC3C,UAAM,KAAK,UAAU,UAAU;AAAA,EAChC;AAAA,EAEA,MAAM,iBAAmC;AACxC,UAAM,QAAQ,MAAM,KAAK,SAAS;AAClC,QAAI,CAAC,MAAM,UAAW,QAAO;AAE7B,WAAO,IAAI,KAAK,MAAM,SAAS,EAAE,QAAQ,IAAI,IAAI,KAAK,MAAO,KAAK,IAAI;AAAA,EACvE;AAAA,EAEA,MAAM,kBAAoC;AACzC,UAAM,eAAe,MAAM,KAAK,gBAAgB;AAChD,QAAI,CAAC,aAAc,QAAO;AAE1B,QAAI;AACH,YAAM,WAAW,MAAM,MAAM,GAAG,YAAY,0BAA0B;AAAA,QACrE,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,oCAAoC;AAAA,QAC/D,MAAM,IAAI,gBAAgB;AAAA,UACzB,YAAY;AAAA,UACZ,eAAe;AAAA,UACf,WAAW;AAAA,QACZ,CAAC,EAAE,SAAS;AAAA,MACb,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AACjB,cAAM,KAAK,MAAM;AACjB,eAAO;AAAA,MACR;AAEA,YAAM,OAAQ,MAAM,SAAS,KAAK;AAMlC,YAAM,KAAK;AAAA,QACV,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,MACN;AAEA,aAAO;AAAA,IACR,QAAQ;AACP,YAAM,KAAK,MAAM;AACjB,aAAO;AAAA,IACR;AAAA,EACD;AACD;AAEO,IAAM,OAAO,IAAI,YAAY;;;AD3HpC,IAAME,gBAAe,QAAQ,IAAI,oBAAoB;AACrD,IAAM,gBAAgB;AACtB,IAAM,eAAe,oBAAoB,aAAa;AACtD,IAAM,YAAY;AAElB,SAAS,uBAA+B;AACvC,QAAM,QAAQ,IAAI,WAAW,EAAE;AAC/B,SAAO,gBAAgB,KAAK;AAC5B,SAAO,KAAK,OAAO,aAAa,GAAG,KAAK,CAAC,EACvC,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,EAAE;AACpB;AAEA,eAAe,sBAAsB,UAAmC;AACvE,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,OAAO,QAAQ,OAAO,QAAQ;AACpC,QAAM,OAAO,MAAM,OAAO,OAAO,OAAO,WAAW,IAAI;AACvD,SAAO,KAAK,OAAO,aAAa,GAAG,IAAI,WAAW,IAAI,CAAC,CAAC,EACtD,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,EAAE;AACpB;AAEA,SAAS,gBAAwB;AAChC,QAAM,QAAQ,IAAI,WAAW,EAAE;AAC/B,SAAO,gBAAgB,KAAK;AAC5B,SAAO,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE;AACzE;AAEA,eAAe,YAAY,KAA4B;AACtD,QAAM,CAAC,KAAK,GAAG,IAAI,IAClB,QAAQ,aAAa,WAClB,CAAC,QAAQ,GAAG,IACZ,QAAQ,aAAa,UACpB,CAAC,OAAO,MAAM,SAAS,GAAG,IAC1B,CAAC,YAAY,GAAG;AAErB,QAAM,KAAK,MAAM,EAAE,OAAO,UAAU,UAAU,KAAK,CAAC,EAAE,MAAM;AAC7D;AAEA,eAAe,gBACd,eACA,YAAoB,KACF;AAClB,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACvC,QAAI,SAAwB;AAE5B,UAAM,UAAU,WAAW,MAAM;AAChC,cAAQ,MAAM;AACd,aAAO,IAAI,SAAS,mBAAmB,eAAe,CAAC;AAAA,IACxD,GAAG,SAAS;AAEZ,UAAM,UAAU,MAAM;AACrB,mBAAa,OAAO;AACpB,cAAQ,MAAM;AAAA,IACf;AAEA,UAAM,eAAe,CAAC,OAAe,SAAiB,UACrD;AAAA;AAAA,8BAE2B,KAAK,MAAM,KAAK;AAAA,eAC/B,OAAO;AAAA;AAAA;AAAA;AAKpB,QAAI;AACH,eAAS,aAAa,CAAC,KAAK,QAAQ;AACnC,cAAM,MAAM,IAAI;AAAA,UACf,IAAI,OAAO;AAAA,UACX,oBAAoB,aAAa;AAAA,QAClC;AAEA,YAAI,IAAI,aAAa,aAAa;AACjC,gBAAM,OAAO,IAAI,aAAa,IAAI,MAAM;AACxC,gBAAM,QAAQ,IAAI,aAAa,IAAI,OAAO;AAC1C,gBAAM,QAAQ,IAAI,aAAa,IAAI,OAAO;AAE1C,cAAI,UAAU,gBAAgB,WAAW;AAEzC,cAAI,OAAO;AACV,gBAAI,aAAa;AACjB,gBAAI,IAAI,aAAa,gBAAgB,UAAU,KAAK,IAAI,SAAS,CAAC;AAClE,oBAAQ;AACR,mBAAO,IAAI,SAAS,gBAAgB,KAAK,IAAI,aAAa,CAAC;AAC3D;AAAA,UACD;AAEA,cAAI,UAAU,eAAe;AAC5B,gBAAI,aAAa;AACjB,gBAAI;AAAA,cACH;AAAA,gBACC;AAAA,gBACA;AAAA,gBACA;AAAA,cACD;AAAA,YACD;AACA,oBAAQ;AACR,mBAAO,IAAI,SAAS,2BAA2B,eAAe,CAAC;AAC/D;AAAA,UACD;AAEA,cAAI,CAAC,MAAM;AACV,gBAAI,aAAa;AACjB,gBAAI;AAAA,cACH;AAAA,gBACC;AAAA,gBACA;AAAA,gBACA;AAAA,cACD;AAAA,YACD;AACA,oBAAQ;AACR,mBAAO,IAAI,SAAS,yBAAyB,SAAS,CAAC;AACvD;AAAA,UACD;AAEA,cAAI,aAAa;AACjB,cAAI;AAAA,YACH;AAAA,cACC;AAAA,cACA;AAAA,cACA;AAAA,YACD;AAAA,UACD;AAGA,qBAAW,MAAM;AAChB,oBAAQ;AACR,oBAAQ,IAAI;AAAA,UACb,GAAG,GAAG;AACN;AAAA,QACD;AAEA,YAAI,aAAa;AACjB,YAAI,IAAI,WAAW;AAAA,MACpB,CAAC;AAED,aAAO,GAAG,SAAS,CAAC,QAA+B;AAClD,gBAAQ;AACR,YAAI,IAAI,SAAS,cAAc;AAC9B;AAAA,YACC,IAAI;AAAA,cACH,QAAQ,aAAa;AAAA,cACrB;AAAA,YACD;AAAA,UACD;AAAA,QACD,OAAO;AACN,iBAAO,GAAG;AAAA,QACX;AAAA,MACD,CAAC;AAED,aAAO,OAAO,aAAa;AAAA,IAC5B,SAAS,KAAc;AACtB,cAAQ;AACR,aAAO,GAAG;AAAA,IACX;AAAA,EACD,CAAC;AACF;AAEA,eAAe,qBACd,MACA,cAC8B;AAC9B,QAAM,WAAW,MAAM,MAAM,GAAGA,aAAY,0BAA0B;AAAA,IACrE,QAAQ;AAAA,IACR,SAAS;AAAA,MACR,gBAAgB;AAAA,IACjB;AAAA,IACA,MAAM,IAAI,gBAAgB;AAAA,MACzB,YAAY;AAAA,MACZ;AAAA,MACA,cAAc;AAAA,MACd,WAAW;AAAA,MACX,eAAe;AAAA,IAChB,CAAC,EAAE,SAAS;AAAA,EACb,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AACjB,UAAM,QAAQ,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACpD,UAAM,IAAI;AAAA,MACR,MAAyC,qBACzC;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAEA,SAAO,SAAS,KAAK;AACtB;AAEO,IAAM,eAAe,IAAIC,SAAQ,OAAO,EAC7C,YAAY,oBAAoB,EAChC,OAAO,gBAAgB,sCAAsC,EAC7D,OAAO,OAAO,SAAS,YAAY;AACnC,QAAM,gBAAgB,QAAQ,gBAAgB;AAC9C,QAAM,OAAO,cAAc,QAAQ;AAEnC,MAAI;AAEH,QAAI,MAAM,KAAK,WAAW,GAAG;AAC5B,UAAI,MAAM;AACT,qBAAa,EAAE,iBAAiB,KAAK,GAAG,IAAI;AAAA,MAC7C,OAAO;AACN,gBAAQ;AAAA,UACPC,OAAM;AAAA,YACL;AAAA,UACD;AAAA,QACD;AAAA,MACD;AACA;AAAA,IACD;AAEA,QAAI,CAAC,MAAM;AACV,cAAQ,IAAIA,OAAM,KAAK,wBAAwB,CAAC;AAAA,IACjD;AAGA,UAAM,eAAe,qBAAqB;AAC1C,UAAM,gBAAgB,MAAM,sBAAsB,YAAY;AAC9D,UAAM,QAAQ,cAAc;AAG5B,UAAM,UAAU,IAAI,IAAI,GAAGF,aAAY,kBAAkB;AACzD,YAAQ,aAAa,IAAI,aAAa,SAAS;AAC/C,YAAQ,aAAa,IAAI,gBAAgB,YAAY;AACrD,YAAQ,aAAa,IAAI,iBAAiB,MAAM;AAChD,YAAQ,aAAa,IAAI,kBAAkB,aAAa;AACxD,YAAQ,aAAa,IAAI,yBAAyB,MAAM;AACxD,YAAQ,aAAa,IAAI,SAAS,KAAK;AAEvC,QAAI,CAAC,MAAM;AACV,cAAQ,IAAI,yCAAyC;AACrD,cAAQ,IAAI;AAAA,CAAuC;AACnD,cAAQ,IAAIE,OAAM,KAAK,KAAK,QAAQ,SAAS,CAAC,EAAE,CAAC;AACjD,cAAQ,IAAI;AAAA,IACb;AAGA,UAAM,kBAAkB,gBAAgB,KAAK;AAE7C,QAAI,QAAQ,YAAY,OAAO;AAC9B,YAAM,YAAY,QAAQ,SAAS,CAAC;AAAA,IACrC;AAEA,UAAM,UAAU,IAAI,8BAA8B,EAAE,MAAM;AAG1D,UAAM,OAAO,MAAM;AAEnB,YAAQ,OAAO;AAGf,UAAM,gBAAgB,MAAM,qBAAqB,MAAM,YAAY;AAGnE,UAAM,KAAK;AAAA,MACV,cAAc;AAAA,MACd,cAAc;AAAA,MACd,cAAc;AAAA,IACf;AAEA,YAAQ,QAAQ,yBAAyB;AAEzC,QAAI,MAAM;AACT,mBAAa,EAAE,SAAS,MAAM,UAAU,KAAK,GAAG,IAAI;AAAA,IACrD,OAAO;AACN,cAAQ,IAAI;AACZ,oBAAc,qCAAqC,KAAK;AACxD,cAAQ,IAAI;AACZ,cAAQ,IAAI,cAAc;AAC1B,cAAQ;AAAA,QACP;AAAA,MACD;AACA,cAAQ,IAAI,yDAAyD;AACrE,cAAQ;AAAA,QACP;AAAA,MACD;AAAA,IACD;AAAA,EACD,SAAS,OAAO;AACf,gBAAY,OAAO,IAAI;AACvB,YAAQ,KAAK,CAAC;AAAA,EACf;AACD,CAAC;;;AEpSF,SAAS,WAAAC,gBAAe;;;ACAxB,SAAS,UAAAC,SAAQ,SAAAC,QAAO,YAAAC,WAAU,aAAAC,kBAAiB;AACnD,SAAS,WAAAC,gBAAe;AACxB,SAAS,QAAAC,aAAY;AACrB,SAAS,KAAAC,UAAS;;;ACHlB,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,SAAAC,QAAO,YAAAC,WAAU,aAAAC,kBAAiB;AAC3C,SAAS,QAAAC,aAAY;AACrB,SAAS,KAAAC,UAAS;AAElB,IAAMC,sBAAqB;AAC3B,IAAMC,uBAAsB;AAErB,IAAM,sBAAsBF,GAAE,OAAO;AAAA,EAC3C,OAAOA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,UAAUA,GACR,OAAO;AAAA,IACP,OAAOA,GAAE,OAAO,EAAE,SAAS;AAAA,IAC3B,UAAUA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,CAAC,EACA,SAAS;AACZ,CAAC;AAID,IAAI;AAEJ,SAAS,uBAA+B;AACvC,SAAOD,MAAK,QAAQ,IAAI,GAAGE,qBAAoBC,oBAAmB;AACnE;AAEA,SAAS,sBAA8B;AACtC,SAAOH,MAAK,QAAQ,IAAI,GAAGE,mBAAkB;AAC9C;AAEO,SAAS,mBAA4B;AAC3C,SAAON,YAAW,oBAAoB,CAAC;AACxC;AAEA,eAAsB,oBAAmD;AACxE,MAAI,uBAAuB,QAAW;AACrC,WAAO;AAAA,EACR;AAEA,QAAM,aAAa,qBAAqB;AAExC,MAAI;AACH,UAAM,UAAU,MAAME,UAAS,YAAY,OAAO;AAClD,yBAAqB,oBAAoB,MAAM,KAAK,MAAM,OAAO,CAAC;AAClE,WAAO;AAAA,EACR,QAAQ;AAEP,yBAAqB;AACrB,WAAO;AAAA,EACR;AACD;AAEA,eAAsB,kBACrBM,SACgB;AAChB,QAAM,YAAY,oBAAoB;AACtC,QAAM,aAAa,qBAAqB;AAGxC,QAAMP,OAAM,WAAW,EAAE,WAAW,KAAK,CAAC;AAG1C,QAAM,WAAY,MAAM,kBAAkB,KAAM,CAAC;AACjD,QAAM,SAAS,oBAAoB,MAAM,EAAE,GAAG,UAAU,GAAGO,QAAO,CAAC;AAEnE,QAAML,WAAU,YAAY,KAAK,UAAU,QAAQ,MAAM,GAAI,GAAG,OAAO;AAGvE,uBAAqB;AACtB;;;AD/DA,IAAMM,cAAaC,MAAKC,SAAQ,GAAG,WAAW;AAC9C,IAAM,cAAcD,MAAKD,aAAY,aAAa;AAElD,IAAM,eAAeG,GAAE,OAAO;AAAA,EAC7B,UAAUA,GACR,OAAO;AAAA,IACP,OAAOA,GAAE,OAAO,EAAE,QAAQ,0BAA0B;AAAA,IACpD,UAAUA,GAAE,OAAO,EAAE,QAAQ,EAAE;AAAA,EAChC,CAAC,EACA,QAAQ,OAAO,EAAE,OAAO,4BAA4B,UAAU,GAAG,EAAE;AAAA,EACrE,aAAaA,GAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,IAAI;AAChD,CAAC;AAID,eAAeC,mBAAiC;AAC/C,QAAMC,OAAML,aAAY,EAAE,WAAW,KAAK,CAAC;AAC5C;AAEA,eAAe,aAA8B;AAC5C,QAAMI,iBAAgB;AACtB,MAAI;AACH,UAAME,QAAO,WAAW;AACxB,UAAM,UAAU,MAAMC,UAAS,aAAa,OAAO;AACnD,WAAO,aAAa,MAAM,KAAK,MAAM,OAAO,CAAC;AAAA,EAC9C,QAAQ;AACP,WAAO,aAAa,MAAM,CAAC,CAAC;AAAA,EAC7B;AACD;AAEA,eAAe,YAAYC,SAA+B;AACzD,QAAMJ,iBAAgB;AACtB,QAAMK,WAAU,aAAa,KAAK,UAAUD,SAAQ,MAAM,CAAC,GAAG,OAAO;AACtE;AAEA,IAAM,gBAAN,MAAoB;AAAA,EACX,cAA6B;AAAA,EAErC,MAAc,YAA6B;AAC1C,QAAI,CAAC,KAAK,aAAa;AACtB,WAAK,cAAc,MAAM,WAAW;AAAA,IACrC;AACA,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,MAAc,WAAWA,SAA+B;AACvD,SAAK,cAAcA;AACnB,UAAM,YAAYA,OAAM;AAAA,EACzB;AAAA,EAEA,MAAM,cAA2C;AAChD,UAAMA,UAAS,MAAM,KAAK,UAAU;AACpC,WAAOA,QAAO;AAAA,EACf;AAAA,EAEA,MAAM,uBAAoD;AACzD,UAAM,eAAe,MAAM,KAAK,UAAU;AAC1C,UAAM,gBAAgB,MAAM,kBAAkB;AAE9C,WAAO;AAAA,MACN,GAAG,aAAa;AAAA,MAChB,GAAG,eAAe;AAAA,IACnB;AAAA,EACD;AAAA,EAEA,MAAM,oBAA4C;AACjD,UAAM,gBAAgB,MAAM,kBAAkB;AAC9C,QAAI,eAAe,OAAO;AACzB,aAAO,cAAc;AAAA,IACtB;AACA,WAAO,KAAK,eAAe;AAAA,EAC5B;AAAA,EAEA,MAAM,YAAY,UAAsD;AACvE,UAAMA,UAAS,MAAM,KAAK,UAAU;AACpC,IAAAA,QAAO,WAAW,EAAE,GAAGA,QAAO,UAAU,GAAG,SAAS;AACpD,UAAM,KAAK,WAAWA,OAAM;AAAA,EAC7B;AAAA,EAEA,MAAM,iBAAyC;AAC9C,UAAMA,UAAS,MAAM,KAAK,UAAU;AACpC,WAAOA,QAAO;AAAA,EACf;AAAA,EAEA,MAAM,eAAe,IAAkC;AACtD,UAAMA,UAAS,MAAM,KAAK,UAAU;AACpC,IAAAA,QAAO,cAAc;AACrB,UAAM,KAAK,WAAWA,OAAM;AAAA,EAC7B;AAAA,EAEA,MAAM,QAAuB;AAC5B,UAAM,cAAc,aAAa,MAAM,CAAC,CAAC;AACzC,UAAM,KAAK,WAAW,WAAW;AAAA,EAClC;AACD;AAEO,IAAM,SAAS,IAAI,cAAc;;;ADhGjC,IAAM,gBAAgB,IAAIE,SAAQ,QAAQ,EAC/C,YAAY,uBAAuB,EACnC,OAAO,OAAO,GAAG,YAAY;AAC7B,QAAM,gBAAgB,QAAQ,gBAAgB;AAC9C,QAAM,OAAO,cAAc,QAAQ;AAEnC,MAAI;AACH,QAAI,CAAE,MAAM,KAAK,WAAW,GAAI;AAC/B,UAAI,MAAM;AACT,qBAAa,EAAE,kBAAkB,KAAK,GAAG,IAAI;AAAA,MAC9C,OAAO;AACN,gBAAQ,IAAI,0BAA0B;AAAA,MACvC;AACA;AAAA,IACD;AAGA,UAAM,KAAK,MAAM;AACjB,UAAM,OAAO,MAAM;AAEnB,QAAI,MAAM;AACT,mBAAa,EAAE,SAAS,KAAK,GAAG,IAAI;AAAA,IACrC,OAAO;AACN,oBAAc,6BAA6B,KAAK;AAAA,IACjD;AAAA,EACD,SAAS,OAAO;AACf,gBAAY,OAAO,IAAI;AACvB,YAAQ,KAAK,CAAC;AAAA,EACf;AACD,CAAC;;;AGnCF,SAAS,WAAAC,iBAAe;;;ACAxB,SAAS,WAAAC,gBAAe;AACxB,OAAOC,UAAS;;;ACEhB,IAAMC,gBAAe,QAAQ,IAAI,oBAAoB;AAY9C,IAAM,WAAN,cAAuB,SAAS;AAAA,EACtC,YACC,SACA,MACO,YACP,SACC;AACD,UAAM,SAAS,MAAM,OAAO;AAHrB;AAIP,SAAK,OAAO;AAAA,EACb;AACD;AAEA,eAAe,QACd,QACA,MACA,SAKa;AACb,QAAM;AAAA,IACL;AAAA,IACA,cAAc;AAAA,IACd,SAAS,eAAe,CAAC;AAAA,EAC1B,IAAI,WAAW,CAAC;AAEhB,QAAM,UAAkC;AAAA,IACvC,gBAAgB;AAAA,IAChB,GAAG;AAAA,EACJ;AAEA,MAAI,aAAa;AAChB,UAAM,QAAQ,MAAM,KAAK,eAAe;AACxC,QAAI,CAAC,OAAO;AACX,YAAM,IAAI;AAAA,QACT;AAAA,MACD;AAAA,IACD;AACA,YAAQ,gBAAgB,UAAU,KAAK;AAAA,EACxC;AAEA,QAAM,MAAM,GAAGA,aAAY,GAAG,IAAI;AAElC,QAAM,WAAW,MAAM,MAAM,KAAK;AAAA,IACjC;AAAA,IACA;AAAA,IACA,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,EACrC,CAAC;AAGD,MAAI,SAAS,WAAW,KAAK;AAC5B,WAAO;AAAA,EACR;AAEA,QAAM,OAAQ,MAAM,SAAS,KAAK;AAElC,MAAI,CAAC,SAAS,MAAM,KAAK,OAAO;AAC/B,UAAM,QAAQ,KAAK,SAAS;AAAA,MAC3B,MAAM;AAAA,MACN,SAAS,8BAA8B,SAAS,MAAM;AAAA,IACvD;AAGA,QAAI,SAAS,WAAW,KAAK;AAC5B,YAAM,YAAY,MAAM,KAAK,gBAAgB;AAC7C,UAAI,WAAW;AAEd,eAAO,QAAW,QAAQ,MAAM,OAAO;AAAA,MACxC;AACA,YAAM,IAAI;AAAA,QACT;AAAA,MACD;AAAA,IACD;AAEA,UAAM,IAAI;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,MAAM;AAAA,IACP;AAAA,EACD;AAEA,SAAO,KAAK;AACb;AAEO,IAAM,MAAM;AAAA,EAClB,KAAK,CAAI,MAAc,YACtB,QAAW,OAAO,MAAM,OAAO;AAAA,EAEhC,MAAM,CACL,MACA,MACA,YACI,QAAW,QAAQ,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;AAAA,EAElD,QAAQ,CAAI,MAAc,YACzB,QAAW,UAAU,MAAM,OAAO;AAAA,EAEnC,YAAY,MAAMA;AACnB;;;ADvGO,IAAM,gBAAgB,IAAIC,SAAQ,QAAQ,EAC/C,YAAY,wCAAwC,EACpD,SAAS,UAAU,0BAA0B,EAC7C,OAAO,YAAY,iDAAiD,EACpE,OAAO,OAAO,MAAc,SAAS,YAAY;AACjD,QAAM,gBAAgB,QAAQ,gBAAgB;AAC9C,QAAM,OAAO,cAAc,QAAQ;AAEnC,MAAI;AACH,UAAM,UAAUC,KAAI,yBAAyB,EAAE,MAAM;AAErD,UAAM,SAAS,MAAM,IAAI,KAAwB,mBAAmB;AAAA,MACnE;AAAA,IACD,CAAC;AAED,YAAQ,QAAQ,qBAAqB;AAGrC,UAAM,mBAAmB,CAAC,QAAQ,UAAU,iBAAiB;AAE7D,QAAI,kBAAkB;AACrB,YAAM,kBAAkB,EAAE,OAAO,OAAO,GAAG,CAAC;AAAA,IAC7C,OAAO;AACN,YAAM,OAAO,eAAe,OAAO,EAAE;AAAA,IACtC;AAEA,QAAI,MAAM;AACT;AAAA,QACC,EAAE,GAAG,QAAQ,OAAO,mBAAmB,YAAY,SAAS;AAAA,QAC5D;AAAA,MACD;AAAA,IACD,OAAO;AACN,YAAM,QAAQ,mBACX,uBACA;AACH,cAAQ,IAAI;AACZ;AAAA,QACC,gBAAgB,IAAI,2BAA2B,KAAK;AAAA,QACpD;AAAA,MACD;AACA,cAAQ,IAAI;AACZ,cAAQ,IAAI,kBAAkB,OAAO,EAAE,EAAE;AACzC,cAAQ,IAAI,kBAAkB,OAAO,SAAS,EAAE;AAChD,cAAQ,IAAI,kBAAkB,OAAO,UAAU,EAAE;AACjD,cAAQ,IAAI;AACZ,cAAQ,IAAI,aAAa;AACzB,cAAQ,IAAI,0CAA0C;AACtD,cAAQ,IAAI,qBAAqB;AACjC,cAAQ,IAAI,uBAAuB;AAAA,IACpC;AAAA,EACD,SAAS,OAAO;AACf,gBAAY,OAAO,IAAI;AACvB,YAAQ,KAAK,CAAC;AAAA,EACf;AACD,CAAC;;;AElEF,SAAS,WAAAC,gBAAe;AACxB,OAAOC,UAAS;AAOT,IAAM,gBAAgB,IAAIC,SAAQ,QAAQ,EAC/C,YAAY,mDAAmD,EAC/D,OAAO,iBAAiB,wBAAwB,EAChD,OAAO,gBAAgB,qBAAqB,EAC5C,OAAO,aAAa,2BAA2B,EAC/C,OAAO,iBAAiB,iBAAiB,EACzC,OAAO,OAAO,SAAS,YAAY;AACnC,QAAM,gBAAgB,QAAQ,gBAAgB;AAC9C,QAAM,OAAO,cAAc,QAAQ;AAEnC,MAAI;AACH,QAAI,QAAQ,QAAQ;AAEpB,QAAI,CAAC,OAAO;AACX,cAAQ,MAAM,OAAO,eAAe;AACpC,UAAI,CAAC,OAAO;AACX,cAAM,IAAI;AAAA,UACT;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAEA,UAAM,UAAUC,KAAI,wBAAwB,EAAE,MAAM;AAEpD,UAAM,SAAS,MAAM,IAAI;AAAA,MACxB,mBAAmB,KAAK;AAAA,MACxB;AAAA,QACC,UAAU,QAAQ;AAAA,QAClB,KAAK,QAAQ;AAAA,QACb,SAAS,QAAQ,WAAW;AAAA,MAC7B;AAAA,IACD;AAEA,YAAQ,QAAQ,sBAAsB;AAEtC,QAAI,MAAM;AACT,mBAAa,QAAQ,IAAI;AAAA,IAC1B,OAAO;AACN,cAAQ,IAAI;AACZ,oBAAc,wBAAwB,KAAK;AAC3C,cAAQ,IAAI;AACZ,cAAQ,IAAI,iBAAiB,OAAO,WAAW,GAAG,EAAE;AACpD,UAAI,OAAO,WAAW,KAAK;AAC1B,gBAAQ,IAAI,iBAAiB,OAAO,WAAW,GAAG,EAAE;AAAA,MACrD;AACA,cAAQ,IAAI;AACZ,UAAI,OAAO,WAAW,MAAM;AAC3B,gBAAQ,IAAI,SAAS,OAAO,WAAW,IAAI,EAAE;AAAA,MAC9C;AAAA,IACD;AAAA,EACD,SAAS,OAAO;AACf,gBAAY,OAAO,IAAI;AACvB,YAAQ,KAAK,CAAC;AAAA,EACf;AACD,CAAC;;;AC9DF,OAAOC,YAAW;AAClB,SAAS,WAAAC,gBAAe;AACxB,OAAOC,UAAS;AAOT,IAAM,cAAc,IAAIC,SAAQ,MAAM,EAC3C,YAAY,oCAAoC,EAChD,OAAO,SAAS,8BAA8B,EAC9C,OAAO,OAAO,SAAS,YAAY;AACnC,QAAM,gBAAgB,QAAQ,gBAAgB;AAC9C,QAAM,OAAO,cAAc,QAAQ;AAEnC,MAAI;AACH,UAAM,UAAUC,KAAI,kBAAkB,EAAE,MAAM;AAE9C,UAAM,OAAO,MAAM,IAAI;AAAA,MACtB,kBAAkB,QAAQ,MAAM,cAAc,EAAE;AAAA,IACjD;AAEA,YAAQ,KAAK;AAEb,UAAM,cAAc,MAAM,OAAO,eAAe;AAEhD,QAAI,MAAM;AACT;AAAA,QACC;AAAA,UACC,MAAM,KAAK,IAAI,CAAC,OAAY;AAAA,YAC3B,GAAG;AAAA,YACH,UAAU,EAAE,OAAO;AAAA,UACpB,EAAE;AAAA,UACF;AAAA,QACD;AAAA,QACA;AAAA,MACD;AAAA,IACD,OAAO;AACN,UAAI,KAAK,WAAW,GAAG;AACtB,gBAAQ,IAAI,gBAAgB;AAC5B,gBAAQ,IAAI,wDAAwD;AACpE;AAAA,MACD;AAEA,cAAQ,IAAIC,OAAM,KAAK,WAAW,CAAC;AAEnC,YAAM,OAAO,KAAK,IAAI,CAAC,MAAW;AACjC,cAAM,WAAW,EAAE,OAAO;AAC1B,cAAM,cACL,EAAE,WAAW,WACVA,OAAM,QACN,EAAE,WAAW,YACZA,OAAM,MACNA,OAAM;AAEX,eAAO;AAAA,UACN,WACGA,OAAM,KAAK,KAAK,EAAE,GAAG,MAAM,GAAG,CAAC,CAAC,EAAE,IAClC,KAAK,EAAE,GAAG,MAAM,GAAG,CAAC,CAAC;AAAA,UACxB,EAAE;AAAA,UACF,YAAY,EAAE,MAAM;AAAA,UACpB,EAAE;AAAA,UACF,EAAE,YAAY,IAAI,KAAK,EAAE,SAAS,EAAE,eAAe,IAAI;AAAA,QACxD;AAAA,MACD,CAAC;AAED;AAAA,QACC,CAAC,MAAM,QAAQ,UAAU,eAAe,SAAS;AAAA,QACjD;AAAA,QACA;AAAA,MACD;AAEA,cAAQ,IAAI;AACZ,UAAI,aAAa;AAChB,gBAAQ,IAAI,eAAeA,OAAM,KAAK,YAAY,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE;AAAA,MACjE;AACA,cAAQ,IAAI,0CAA0C;AAAA,IACvD;AAAA,EACD,SAAS,OAAO;AACf,gBAAY,OAAO,IAAI;AACvB,YAAQ,KAAK,CAAC;AAAA,EACf;AACD,CAAC;;;ACnFF,OAAOC,YAAW;AAClB,SAAS,WAAAC,gBAAe;AACxB,OAAOC,UAAS;AAOT,IAAM,gBAAgB,IAAIC,SAAQ,QAAQ,EAC/C,YAAY,iCAAiC,EAC7C,OAAO,iBAAiB,iBAAiB,EACzC,OAAO,OAAO,SAAS,YAAY;AACnC,QAAM,gBAAgB,QAAQ,gBAAgB;AAC9C,QAAM,OAAO,cAAc,QAAQ;AAEnC,MAAI;AACH,QAAI,QAAQ,QAAQ;AAEpB,QAAI,CAAC,OAAO;AACX,cAAQ,MAAM,OAAO,eAAe;AACpC,UAAI,CAAC,OAAO;AACX,cAAM,IAAI;AAAA,UACT;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAEA,UAAM,UAAUC,KAAI,wBAAwB,EAAE,MAAM;AACpD,UAAM,SAAS,MAAM,IAAI,IAAS,mBAAmB,KAAK,EAAE;AAC5D,YAAQ,KAAK;AAEb,QAAI,MAAM;AACT,mBAAa,QAAQ,IAAI;AAAA,IAC1B,OAAO;AACN,YAAM,cACL,OAAO,WAAW,WAAWC,OAAM,QAAQA,OAAM;AAElD;AAAA,QACC;AAAA,UACC,EAAE,OAAO,UAAU,OAAO,OAAO,GAAG;AAAA,UACpC,EAAE,OAAO,QAAQ,OAAO,OAAO,KAAK;AAAA,UACpC,EAAE,OAAO,UAAU,OAAO,YAAY,OAAO,MAAM,EAAE;AAAA,UACrD,EAAE,OAAO,cAAc,OAAO,OAAO,UAAU;AAAA,UAC/C,EAAE,OAAO,eAAe,OAAO,OAAO,WAAW;AAAA,UACjD,EAAE,OAAO,WAAW,OAAO,OAAO,UAAU;AAAA,UAC5C,EAAE,OAAO,WAAW,OAAO,OAAO,aAAa,MAAM;AAAA,QACtD;AAAA,QACA;AAAA,MACD;AAAA,IACD;AAAA,EACD,SAAS,OAAO;AACf,gBAAY,OAAO,IAAI;AACvB,YAAQ,KAAK,CAAC;AAAA,EACf;AACD,CAAC;;;ACvDF,SAAS,WAAAC,gBAAe;AACxB,OAAOC,UAAS;AAMT,IAAM,cAAc,IAAIC,SAAQ,MAAM,EAC3C,YAAY,mCAAmC,EAC/C,OAAO,iBAAiB,iBAAiB,EACzC,OAAO,OAAO,SAAS,YAAY;AACnC,QAAM,gBAAgB,QAAQ,gBAAgB;AAC9C,QAAM,OAAO,cAAc,QAAQ;AAEnC,MAAI;AACH,QAAI,QAAQ,QAAQ;AAEpB,QAAI,CAAC,OAAO;AACX,cAAQ,MAAM,OAAO,eAAe;AACpC,UAAI,CAAC,OAAO;AACX,cAAM,IAAI,SAAS,6CAA6C;AAAA,MACjE;AAAA,IACD;AAEA,UAAM,UAAUC,KAAI,yBAAyB,EAAE,MAAM;AACrD,UAAM,IAAI,OAAO,mBAAmB,KAAK,EAAE;AAC3C,YAAQ,QAAQ,qBAAqB;AAGrC,QAAK,MAAM,OAAO,eAAe,MAAO,OAAO;AAC9C,YAAM,OAAO,eAAe,IAAI;AAAA,IACjC;AAEA,QAAI,MAAM;AACT,mBAAa,EAAE,SAAS,MAAM,GAAG,IAAI;AAAA,IACtC,OAAO;AACN,oBAAc,uCAAuC,KAAK;AAAA,IAC3D;AAAA,EACD,SAAS,OAAO;AACf,gBAAY,OAAO,IAAI;AACvB,YAAQ,KAAK,CAAC;AAAA,EACf;AACD,CAAC;;;AC1CF,OAAOC,YAAW;AAClB,SAAS,WAAAC,gBAAe;AACxB,OAAOC,UAAS;AAWT,IAAM,cAAc,IAAIC,SAAQ,MAAM,EAC3C,YAAY,gCAAgC,EAC5C,SAAS,UAAU,4CAA4C,EAC/D,SAAS,aAAa,6BAA6B,EACnD,OAAO,iBAAiB,iBAAiB,EACzC;AAAA,EACA,OAAO,MAA0B,MAAgB,SAAS,YAAY;AACrE,UAAM,gBAAgB,QAAQ,gBAAgB;AAC9C,UAAM,OAAO,cAAc,QAAQ;AAEnC,QAAI;AACH,UAAI,QAAQ,QAAQ;AAEpB,UAAI,CAAC,OAAO;AACX,gBAAQ,MAAM,OAAO,eAAe;AACpC,YAAI,CAAC,OAAO;AACX,gBAAM,IAAI;AAAA,YACT;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAEA,UAAI,CAAC,MAAM;AAEV,cAAM,UAAUC,KAAI,6BAA6B,EAAE,MAAM;AACzD,cAAM,SAAS,MAAM,IAAI;AAAA,UACxB,mBAAmB,KAAK;AAAA,UACxB,EAAE,QAAQ,OAAO;AAAA,QAClB;AACA,gBAAQ,KAAK;AAEb,cAAM,QAAQ,OAAO;AAErB,YAAI,MAAM;AACT,uBAAa,EAAE,MAAM,GAAG,IAAI;AAAA,QAC7B,OAAO;AACN,cAAI,MAAM,WAAW,GAAG;AACvB,oBAAQ,IAAI,qBAAqB;AAAA,UAClC,OAAO;AACN,oBAAQ,IAAIC,OAAM,KAAK,sBAAsB,CAAC;AAC9C;AAAA,cACC,CAAC,QAAQ,aAAa;AAAA,cACtB,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,eAAe,gBAAgB,CAAC;AAAA,cAC5D;AAAA,YACD;AACA,oBAAQ;AAAA,cACP;AAAA;AAAA,YACD;AAAA,UACD;AAAA,QACD;AAAA,MACD,OAAO;AAEN,YAAI,WAAoC,CAAC;AACzC,YAAI,KAAK,SAAS,GAAG;AACpB,cAAI;AACH,uBAAW,KAAK,MAAM,KAAK,KAAK,GAAG,CAAC;AAAA,UACrC,QAAQ;AACP,kBAAM,IAAI;AAAA,cACT;AAAA,YACD;AAAA,UACD;AAAA,QACD;AAEA,cAAM,UAAUD,KAAI,iBAAiB,IAAI,MAAM,EAAE,MAAM;AACvD,cAAM,YAAY,KAAK,IAAI;AAC3B,cAAM,SAAS,MAAM,IAAI;AAAA,UACxB,mBAAmB,KAAK;AAAA,UACxB;AAAA,YACC,QAAQ;AAAA,YACR;AAAA,YACA,MAAM;AAAA,UACP;AAAA,QACD;AACA,cAAM,WAAW,OAAO,YAAY,KAAK,IAAI,IAAI;AACjD,gBAAQ,KAAK;AAEb,cAAM,SAAwB;AAAA,UAC7B;AAAA,UACA,OAAO;AAAA,UACP,QAAQ,OAAO;AAAA,UACf;AAAA,QACD;AAEA,YAAI,MAAM;AACT,uBAAa,QAAQ,IAAI;AAAA,QAC1B,OAAO;AACN,kBAAQ,IAAIC,OAAM,KAAK,kBAAkB,CAAC;AAC1C,kBAAQ,IAAIA,OAAM,KAAK,OAAO,GAAG,IAAI;AACrC,kBAAQ,IAAIA,OAAM,KAAK,QAAQ,GAAG,KAAK,UAAU,QAAQ,CAAC;AAC1D,kBAAQ,IAAIA,OAAM,KAAK,WAAW,GAAG,GAAG,QAAQ,IAAI;AACpD,kBAAQ,IAAIA,OAAM,KAAK,SAAS,CAAC;AACjC,kBAAQ,IAAI,KAAK,UAAU,OAAO,QAAQ,MAAM,CAAC,CAAC;AAAA,QACnD;AAAA,MACD;AAAA,IACD,SAAS,OAAO;AACf,kBAAY,OAAO,IAAI;AACvB,cAAQ,KAAK,CAAC;AAAA,IACf;AAAA,EACD;AACD;;;AChHD,SAAS,WAAAC,iBAAe;AACxB,OAAOC,UAAS;AAWT,IAAM,aAAa,IAAIC,UAAQ,KAAK,EACzC,YAAY,8CAA8C,EAC1D,SAAS,UAAU,wBAAwB,EAC3C,OAAO,YAAY,iDAAiD,EACpE,OAAO,OAAO,MAAc,SAAS,YAAY;AACjD,QAAM,gBAAgB,QAAQ,gBAAgB;AAC9C,QAAM,OAAO,cAAc,QAAQ;AAEnC,MAAI;AACH,UAAM,UAAUC,KAAI,kBAAkB,EAAE,MAAM;AAG9C,UAAM,OAAO,MAAM,IAAI,IAAqB,iBAAiB;AAE7D,YAAQ,KAAK;AAGb,UAAM,MAAM,KAAK,KAAK,CAAC,MAAW,EAAE,SAAS,IAAI;AAEjD,QAAI,CAAC,KAAK;AACT,YAAM,IAAI;AAAA,QACT,QAAQ,IAAI;AAAA,MACb;AAAA,IACD;AAEA,QAAI,IAAI,WAAW,UAAU;AAC5B,YAAM,IAAI;AAAA,QACT,QAAQ,IAAI,QAAQ,IAAI,MAAM;AAAA,MAC/B;AAAA,IACD;AAGA,UAAM,mBAAmB,CAAC,QAAQ,UAAU,iBAAiB;AAE7D,QAAI,kBAAkB;AACrB,YAAM,kBAAkB,EAAE,OAAO,IAAI,GAAG,CAAC;AAAA,IAC1C,OAAO;AACN,YAAM,OAAO,eAAe,IAAI,EAAE;AAAA,IACnC;AAEA,QAAI,MAAM;AACT;AAAA,QACC,EAAE,UAAU,KAAK,OAAO,mBAAmB,YAAY,SAAS;AAAA,QAChE;AAAA,MACD;AAAA,IACD,OAAO;AACN,YAAM,QAAQ,mBAAmB,cAAc;AAC/C,oBAAc,kBAAkB,IAAI,KAAK,KAAK,IAAI,KAAK;AACvD,cAAQ,IAAI;AACZ,cAAQ,IAAI,kBAAkB,IAAI,EAAE,EAAE;AACtC,cAAQ,IAAI,kBAAkB,IAAI,UAAU,EAAE;AAC9C,cAAQ,IAAI;AACZ,cAAQ,IAAI,aAAa;AACzB,cAAQ,IAAI,8BAA8B;AAC1C,cAAQ,IAAI,qBAAqB;AACjC,cAAQ,IAAI,uBAAuB;AAAA,IACpC;AAAA,EACD,SAAS,OAAO;AACf,gBAAY,OAAO,IAAI;AACvB,YAAQ,KAAK,CAAC;AAAA,EACf;AACD,CAAC;;;ARhEK,IAAM,aAAa,IAAIC,UAAQ,KAAK,EACzC,YAAY,iCAAiC,EAC7C,WAAW,aAAa,EACxB,WAAW,WAAW,EACtB,WAAW,UAAU,EACrB,WAAW,aAAa,EACxB,WAAW,WAAW,EACtB,WAAW,WAAW,EACtB,WAAW,aAAa;;;ASjB1B,SAAS,WAAAC,iBAAe;;;ACAxB,OAAOC,YAAW;AAClB,SAAS,WAAAC,iBAAe;AACxB,OAAOC,UAAS;AAMT,IAAMC,eAAc,IAAIC,UAAQ,MAAM,EAC3C,YAAY,yBAAyB,EACrC,OAAO,OAAO,GAAG,YAAY;AAC7B,QAAM,gBAAgB,QAAQ,gBAAgB;AAC9C,QAAM,OAAO,cAAc,QAAQ;AAEnC,MAAI;AACH,UAAM,UAAUC,KAAI,2BAA2B,EAAE,MAAM;AAEvD,UAAM,SAAS,MAAM,IAAI,IAAqB,iBAAiB;AAE/D,YAAQ,KAAK;AAEb,UAAM,EAAE,MAAM,YAAY,IAAI;AAE9B,QAAI,MAAM;AACT;AAAA,QACC;AAAA,UACC,MAAM,KAAK,IAAI,CAAC,OAAY;AAAA,YAC3B,GAAG;AAAA,YACH,UAAU,EAAE,OAAO;AAAA,UACpB,EAAE;AAAA,UACF;AAAA,QACD;AAAA,QACA;AAAA,MACD;AAAA,IACD,OAAO;AACN,UAAI,KAAK,WAAW,GAAG;AACtB,gBAAQ,IAAI,yBAAyB;AACrC;AAAA,MACD;AAEA,cAAQ,IAAIC,OAAM,KAAK,oBAAoB,CAAC;AAE5C,YAAM,OAAO,KAAK,IAAI,CAAC,MAAW;AACjC,cAAM,WAAW,EAAE,OAAO;AAC1B,eAAO;AAAA,UACN,WAAWA,OAAM,KAAK,KAAK,EAAE,IAAI,EAAE,IAAI,KAAK,EAAE,IAAI;AAAA,UAClD,EAAE;AAAA,UACF,EAAE;AAAA,QACH;AAAA,MACD,CAAC;AAED,kBAAY,CAAC,QAAQ,QAAQ,MAAM,GAAG,MAAM,KAAK;AAEjD,cAAQ,IAAI;AACZ,UAAI,aAAa;AAChB,cAAM,YAAY,KAAK,KAAK,CAAC,MAAW,EAAE,OAAO,WAAW;AAC5D,YAAI,WAAW;AACd,kBAAQ,IAAI,wBAAwBA,OAAM,KAAK,UAAU,IAAI,CAAC,EAAE;AAAA,QACjE;AAAA,MACD;AACA,cAAQ,IAAI,mDAAmD;AAAA,IAChE;AAAA,EACD,SAAS,OAAO;AACf,gBAAY,OAAO,IAAI;AACvB,YAAQ,KAAK,CAAC;AAAA,EACf;AACD,CAAC;;;AClEF,SAAS,WAAAC,iBAAe;AACxB,OAAOC,WAAS;AAWT,IAAM,gBAAgB,IAAIC,UAAQ,QAAQ,EAC/C,YAAY,oCAAoC,EAChD,SAAS,UAAU,+CAA+C,EAClE,OAAO,OAAO,MAAc,GAAG,YAAY;AAC3C,QAAM,gBAAgB,QAAQ,gBAAgB;AAC9C,QAAM,OAAO,cAAc,QAAQ;AAEnC,MAAI;AACH,UAAM,UAAUC,MAAI,2BAA2B,EAAE,MAAM;AAGvD,UAAM,EAAE,KAAK,IAAI,MAAM,IAAI,IAAqB,iBAAiB;AAGjE,UAAM,MAAM,KAAK,KAAK,CAAC,MAAW,EAAE,SAAS,QAAQ,EAAE,SAAS,IAAI;AAEpE,QAAI,CAAC,KAAK;AACT,cAAQ,KAAK;AACb,YAAM,IAAI;AAAA,QACT,iBAAiB,IAAI;AAAA,QACrB;AAAA,MACD;AAAA,IACD;AAEA,YAAQ,OAAO;AAGf,UAAM,IAAI,KAAwB,0BAA0B;AAAA,MAC3D,OAAO,IAAI;AAAA,IACZ,CAAC;AAED,YAAQ,QAAQ,uBAAuB;AAGvC,WAAO,eAAe,IAAI;AAE1B,QAAI,MAAM;AACT,mBAAa,EAAE,UAAU,IAAI,GAAG,IAAI;AAAA,IACrC,OAAO;AACN,oBAAc,6BAA6B,IAAI,IAAI,KAAK,KAAK;AAC7D,cAAQ,IAAI;AACZ,cAAQ,IAAI,8CAA8C;AAC1D,cAAQ;AAAA,QACP;AAAA,MACD;AAAA,IACD;AAAA,EACD,SAAS,OAAO;AACf,gBAAY,OAAO,IAAI;AACvB,YAAQ,KAAK,CAAC;AAAA,EACf;AACD,CAAC;;;AF1DK,IAAM,aAAa,IAAIC,UAAQ,KAAK,EACzC,YAAY,kCAAkC,EAC9C,WAAWC,YAAW,EACtB,WAAW,aAAa;;;AGP1B,OAAOC,YAAW;AAClB,SAAS,WAAAC,iBAAe;AACxB,OAAOC,WAAS;AAQT,IAAM,cAAc,IAAIC,UAAQ,MAAM,EAC3C,YAAY,8CAA8C,EAC1D,SAAS,YAAY,yBAAyB,EAC9C,OAAO,iBAAiB,iBAAiB,EACzC,OAAO,mBAAmB,qBAAqB,EAC/C,OAAO,mBAAmB,wBAAwB,EAClD,OAAO,OAAO,QAAgB,SAAS,YAAY;AACnD,QAAM,gBAAgB,QAAQ,gBAAgB;AAC9C,QAAM,OAAO,cAAc,QAAQ;AAEnC,MAAI;AACH,QAAI,QAAQ,QAAQ;AAEpB,QAAI,CAAC,OAAO;AACX,cAAQ,MAAM,OAAO,kBAAkB;AACvC,UAAI,CAAC,OAAO;AACX,cAAM,IAAI;AAAA,UACT;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAEA,UAAM,QAAQ,MAAM,KAAK,eAAe;AACxC,QAAI,CAAC,OAAO;AACX,YAAM,IAAI;AAAA,QACT;AAAA,MACD;AAAA,IACD;AAEA,UAAM,WAAW,MAAM,OAAO,qBAAqB;AACnD,UAAM,QAAQ,QAAQ,SAAS,SAAS;AACxC,UAAM,WAAW,QAAQ,WACtB,OAAO,SAAS,QAAQ,UAAU,EAAE,IACpC,SAAS;AAEZ,QAAI,CAAC,MAAM;AACV,cAAQ,IAAI;AACZ,cAAQ,IAAIC,OAAM,KAAK,OAAO,GAAG,MAAM;AACvC,cAAQ,IAAI;AAAA,IACb;AAEA,UAAM,UAAUC,MAAI,kBAAkB,EAAE,MAAM;AAG9C,UAAM,UAAU,IAAI,WAAW;AAC/B,UAAM,WAAW,MAAM,MAAM,GAAG,OAAO,mBAAmB,KAAK,SAAS;AAAA,MACvE,QAAQ;AAAA,MACR,SAAS;AAAA,QACR,gBAAgB;AAAA,QAChB,eAAe,UAAU,KAAK;AAAA,QAC9B,QAAQ;AAAA,MACT;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACpB;AAAA,QACA;AAAA,QACA;AAAA,MACD,CAAC;AAAA,IACF,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AACjB,YAAM,QAAQ,MAAM,SAClB,KAAK,EACL,MAAM,OAAO,EAAE,SAAS,SAAS,WAAW,EAAE;AAChD,cAAQ,KAAK,aAAa;AAC1B,YAAM,IAAI;AAAA,QACT,MAAM,WAAW,8BAA8B,SAAS,MAAM;AAAA,MAC/D;AAAA,IACD;AAEA,YAAQ,KAAK;AAEb,UAAM,QAAoB,CAAC;AAC3B,QAAI,YAAY;AAChB,QAAI,kBAAkB;AAGtB,UAAM,SAAS,SAAS,MAAM,UAAU;AACxC,QAAI,CAAC,QAAQ;AACZ,YAAM,IAAI,MAAM,kBAAkB;AAAA,IACnC;AAEA,UAAM,UAAU,IAAI,YAAY;AAChC,QAAI,SAAS;AAEb,WAAO,MAAM;AACZ,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,KAAM;AAEV,gBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAChD,YAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,eAAS,MAAM,IAAI,KAAK;AAExB,iBAAW,QAAQ,OAAO;AACzB,YAAI,KAAK,WAAW,SAAS,GAAG;AAC/B;AAAA,QACD;AAEA,YAAI,KAAK,WAAW,QAAQ,GAAG;AAC9B,gBAAM,OAAO,KAAK,MAAM,CAAC;AACzB,cAAI,CAAC,QAAQ,SAAS,SAAU;AAEhC,cAAI;AACH,kBAAM,SAAS,KAAK,MAAM,IAAI;AAG9B,gBAAI,OAAO,SAAS,QAAQ;AAC3B,oBAAM,QAAQ;AACd,oBAAM,KAAK,EAAE,MAAM,QAAQ,MAAM,MAAM,QAAQ,CAAC;AAChD,kBAAI,CAAC,QAAQ,MAAM,SAAS;AAC3B,wBAAQ,IAAID,OAAM,MAAM,MAAM,OAAO,CAAC;AAAA,cACvC;AAAA,YACD,WAAW,OAAO,SAAS,aAAa;AACvC,oBAAM,QAAQ;AACd,oBAAM,KAAK;AAAA,gBACV,MAAM;AAAA,gBACN,MAAM,MAAM;AAAA,gBACZ,OAAO,MAAM;AAAA,gBACb,QAAQ,MAAM;AAAA,cACf,CAAC;AAED,kBAAI,CAAC,MAAM;AACV,wBAAQ,IAAIA,OAAM,KAAK,iBAAiB,MAAM,IAAI,EAAE,CAAC;AACrD,oBAAI,MAAM,OAAO,SAAS;AACzB,0BAAQ,IAAIA,OAAM,KAAK,OAAO,MAAM,MAAM,OAAO,EAAE,CAAC;AAAA,gBACrD;AACA,oBAAI,MAAM,QAAQ;AAEjB,wBAAM,cAAc,MAAM,OAAO,MAAM,IAAI;AAC3C,sBAAI,YAAY,SAAS,IAAI;AAC5B,4BAAQ;AAAA,sBACPA,OAAM,KAAK,YAAY,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC;AAAA,oBAC9C;AACA,4BAAQ;AAAA,sBACPA,OAAM;AAAA,wBACL,UAAU,YAAY,SAAS,EAAE;AAAA,sBAClC;AAAA,oBACD;AACA,4BAAQ,IAAIA,OAAM,KAAK,YAAY,MAAM,EAAE,EAAE,KAAK,IAAI,CAAC,CAAC;AAAA,kBACzD,OAAO;AACN,4BAAQ,IAAIA,OAAM,KAAK,MAAM,MAAM,CAAC;AAAA,kBACrC;AAAA,gBACD;AACA,wBAAQ,IAAI;AAAA,cACb;AAAA,YACD,WAAW,OAAO,YAAY,QAAW;AAExC,oBAAM,YAAY;AAClB,0BAAY,UAAU;AACtB,gCAAkB,UAAU,mBAAmB;AAAA,YAChD;AAAA,UACD,QAAQ;AAAA,UAER;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAEA,UAAM,SAAS;AAAA,MACd,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAEA,QAAI,MAAM;AACT,mBAAa,QAAQ,IAAI;AAAA,IAC1B,OAAO;AACN,cAAQ,IAAI;AACZ,cAAQ,IAAIA,OAAM,MAAM,QAAG,GAAG,qBAAqB,SAAS,SAAS;AACrE,UAAI,iBAAiB;AACpB,gBAAQ;AAAA,UACPA,OAAM,OAAO,QAAG;AAAA,UAChB;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,EACD,SAAS,OAAO;AACf,gBAAY,OAAO,IAAI;AACvB,YAAQ,KAAK,CAAC;AAAA,EACf;AACD,CAAC;;;ArBtLF,IAAM,UAAU;AAET,IAAM,UAAU,IAAIE,UAAQ,EACjC,KAAK,UAAU,EACf,YAAY,2CAA2C,EACvD,QAAQ,OAAO,EACf,OAAO,UAAU,wBAAwB,EACzC,OAAO,aAAa,wBAAwB;AAG9C,QAAQ,WAAW,YAAY;AAC/B,QAAQ,WAAW,aAAa;AAGhC,QAAQ,WAAW,WAAW;AAC9B,QAAQ,WAAW,UAAU;AAC7B,QAAQ,WAAW,WAAW;AAC9B,QAAQ,WAAW,UAAU;;;AsBvB7B,QAAQ,MAAM,QAAQ,IAAI;","names":["Command","chalk","chalk","chalk","Command","mkdir","writeFile","join","API_BASE_URL","Command","chalk","Command","access","mkdir","readFile","writeFile","homedir","join","z","existsSync","mkdir","readFile","writeFile","join","z","PROJECT_CONFIG_DIR","PROJECT_CONFIG_FILE","config","CONFIG_DIR","join","homedir","z","ensureConfigDir","mkdir","access","readFile","config","writeFile","Command","Command","Command","ora","API_BASE_URL","Command","ora","Command","ora","Command","ora","chalk","Command","ora","Command","ora","chalk","chalk","Command","ora","Command","ora","chalk","Command","ora","Command","ora","chalk","Command","ora","Command","ora","chalk","Command","ora","Command","ora","Command","Command","chalk","Command","ora","listCommand","Command","ora","chalk","Command","ora","Command","ora","Command","listCommand","chalk","Command","ora","Command","chalk","ora","Command"]}
|
package/package.json
CHANGED
|
@@ -1,61 +1,61 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
2
|
+
"name": "@waniwani/cli",
|
|
3
|
+
"version": "0.0.10",
|
|
4
|
+
"description": "WaniWani CLI for MCP development workflow",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"import": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"bin": {
|
|
13
|
+
"waniwani": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsup",
|
|
20
|
+
"dev": "tsx --watch src/index.ts",
|
|
21
|
+
"typecheck": "tsc --noEmit",
|
|
22
|
+
"lint": "biome check .",
|
|
23
|
+
"lint:fix": "biome check . --write",
|
|
24
|
+
"test": "node --test",
|
|
25
|
+
"prepublishOnly": "rm -rf dist && npm run typecheck && npm run lint && npm run build",
|
|
26
|
+
"release": "npm version patch && npm publish --access public",
|
|
27
|
+
"release:minor": "npm version minor && npm publish --access public",
|
|
28
|
+
"release:major": "npm version major && npm publish --access public"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"chalk": "^5.4.1",
|
|
32
|
+
"commander": "^14.0.2",
|
|
33
|
+
"ora": "^9.1.0",
|
|
34
|
+
"zod": "^4.3.6"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@biomejs/biome": "^2.3.13",
|
|
38
|
+
"@types/node": "^22.10.0",
|
|
39
|
+
"tsup": "^8.3.5",
|
|
40
|
+
"tsx": "^4.19.2",
|
|
41
|
+
"typescript": "^5.7.3"
|
|
42
|
+
},
|
|
43
|
+
"repository": {
|
|
44
|
+
"type": "git",
|
|
45
|
+
"url": "https://github.com/WaniWani-AI/waniwani-cli"
|
|
46
|
+
},
|
|
47
|
+
"keywords": [
|
|
48
|
+
"cli",
|
|
49
|
+
"mcp",
|
|
50
|
+
"waniwani",
|
|
51
|
+
"vercel",
|
|
52
|
+
"sandbox",
|
|
53
|
+
"claude",
|
|
54
|
+
"node",
|
|
55
|
+
"npm",
|
|
56
|
+
"pnpm",
|
|
57
|
+
"yarn"
|
|
58
|
+
],
|
|
59
|
+
"author": "WaniWani",
|
|
60
|
+
"license": "MIT"
|
|
61
61
|
}
|