@waniwani/cli 0.0.29 → 0.0.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3,18 +3,13 @@
3
3
  // src/cli.ts
4
4
  import { Command as Command25 } from "commander";
5
5
 
6
- // src/commands/dev.ts
7
- import { relative as relative2 } from "path";
8
- import chalk2 from "chalk";
9
- import chokidar from "chokidar";
10
- import { Command } from "commander";
11
- import ora from "ora";
6
+ // src/commands/config/index.ts
7
+ import { Command as Command2 } from "commander";
12
8
 
13
- // src/lib/auth.ts
14
- import { access, mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
15
- import { homedir as homedir2 } from "os";
9
+ // src/commands/config/init.ts
10
+ import { existsSync as existsSync2 } from "fs";
16
11
  import { join as join2 } from "path";
17
- import { z as z2 } from "zod";
12
+ import { Command } from "commander";
18
13
 
19
14
  // src/lib/config.ts
20
15
  import { existsSync } from "fs";
@@ -22,13 +17,14 @@ import { mkdir, readFile, writeFile } from "fs/promises";
22
17
  import { homedir } from "os";
23
18
  import { join } from "path";
24
19
  import { z } from "zod";
25
- var LOCAL_DIR = join(process.cwd(), ".waniwani");
26
- var LOCAL_FILE = join(LOCAL_DIR, "settings.json");
27
- var GLOBAL_DIR = join(homedir(), ".waniwani");
28
- var GLOBAL_FILE = join(GLOBAL_DIR, "settings.json");
20
+ var LOCAL_CONFIG_DIR = ".waniwani";
21
+ var CONFIG_FILE_NAME = "settings.json";
22
+ var LOCAL_DIR = join(process.cwd(), LOCAL_CONFIG_DIR);
23
+ var LOCAL_FILE = join(LOCAL_DIR, CONFIG_FILE_NAME);
24
+ var GLOBAL_DIR = join(homedir(), LOCAL_CONFIG_DIR);
25
+ var GLOBAL_FILE = join(GLOBAL_DIR, CONFIG_FILE_NAME);
29
26
  var DEFAULT_API_URL = "https://app.waniwani.ai";
30
27
  var ConfigSchema = z.object({
31
- defaults: z.object({ model: z.string(), maxSteps: z.number() }).default({ model: "claude-sonnet-4-20250514", maxSteps: 10 }),
32
28
  mcpId: z.string().nullable().default(null),
33
29
  apiUrl: z.string().nullable().default(null)
34
30
  });
@@ -60,14 +56,6 @@ var Config = class {
60
56
  await mkdir(this.dir, { recursive: true });
61
57
  await writeFile(this.file, JSON.stringify(data, null, " "));
62
58
  }
63
- async getDefaults() {
64
- return (await this.load()).defaults;
65
- }
66
- async setDefaults(defaults) {
67
- const data = await this.load();
68
- data.defaults = { ...data.defaults, ...defaults };
69
- await this.save(data);
70
- }
71
59
  async getMcpId() {
72
60
  return (await this.load()).mcpId;
73
61
  }
@@ -91,10 +79,176 @@ var Config = class {
91
79
  };
92
80
  var config = new Config();
93
81
  var globalConfig = new Config(true);
82
+ async function initConfigAt(dir, overrides = {}) {
83
+ const configDir = join(dir, LOCAL_CONFIG_DIR);
84
+ const configPath = join(configDir, CONFIG_FILE_NAME);
85
+ await mkdir(configDir, { recursive: true });
86
+ const data = ConfigSchema.parse(overrides);
87
+ await writeFile(configPath, JSON.stringify(data, null, " "), "utf-8");
88
+ return { path: configPath, config: data };
89
+ }
90
+
91
+ // src/lib/errors.ts
92
+ import chalk from "chalk";
93
+ import { ZodError } from "zod";
94
+ var CLIError = class extends Error {
95
+ constructor(message, code, details) {
96
+ super(message);
97
+ this.code = code;
98
+ this.details = details;
99
+ this.name = "CLIError";
100
+ }
101
+ };
102
+ var AuthError = class extends CLIError {
103
+ constructor(message, details) {
104
+ super(message, "AUTH_ERROR", details);
105
+ }
106
+ };
107
+ var McpError = class extends CLIError {
108
+ constructor(message, details) {
109
+ super(message, "MCP_ERROR", details);
110
+ }
111
+ };
112
+ function handleError(error, json) {
113
+ if (error instanceof ZodError) {
114
+ const message = error.issues.map((e) => `${e.path.join(".")}: ${e.message}`).join(", ");
115
+ outputError("VALIDATION_ERROR", `Invalid input: ${message}`, json);
116
+ } else if (error instanceof CLIError) {
117
+ outputError(error.code, error.message, json, error.details);
118
+ } else if (error instanceof Error) {
119
+ outputError("UNKNOWN_ERROR", error.message, json);
120
+ } else {
121
+ outputError("UNKNOWN_ERROR", String(error), json);
122
+ }
123
+ }
124
+ function outputError(code, message, json, details) {
125
+ if (json) {
126
+ console.error(
127
+ JSON.stringify({ success: false, error: { code, message, details } })
128
+ );
129
+ } else {
130
+ console.error(chalk.red(`Error [${code}]:`), message);
131
+ if (details) {
132
+ console.error(chalk.gray("Details:"), JSON.stringify(details, null, 2));
133
+ }
134
+ }
135
+ }
136
+
137
+ // src/lib/output.ts
138
+ import chalk2 from "chalk";
139
+ function formatOutput(data, json) {
140
+ if (json) {
141
+ console.log(JSON.stringify({ success: true, data }, null, 2));
142
+ } else {
143
+ prettyPrint(data);
144
+ }
145
+ }
146
+ function formatSuccess(message, json) {
147
+ if (json) {
148
+ console.log(JSON.stringify({ success: true, message }));
149
+ } else {
150
+ console.log(chalk2.green("\u2713"), message);
151
+ }
152
+ }
153
+ function formatTable(headers, rows, json) {
154
+ if (json) {
155
+ const data = rows.map(
156
+ (row) => Object.fromEntries(headers.map((header, i) => [header, row[i]]))
157
+ );
158
+ console.log(JSON.stringify({ success: true, data }, null, 2));
159
+ } else {
160
+ const colWidths = headers.map(
161
+ (h, i) => Math.max(h.length, ...rows.map((r) => (r[i] || "").length))
162
+ );
163
+ const separator = colWidths.map((w) => "-".repeat(w + 2)).join("+");
164
+ const formatRow = (row) => row.map((cell, i) => ` ${(cell || "").padEnd(colWidths[i])} `).join("|");
165
+ console.log(chalk2.cyan(formatRow(headers)));
166
+ console.log(separator);
167
+ for (const row of rows) {
168
+ console.log(formatRow(row));
169
+ }
170
+ }
171
+ }
172
+ function formatList(items, json) {
173
+ if (json) {
174
+ const data = Object.fromEntries(
175
+ items.map((item) => [item.label, item.value])
176
+ );
177
+ console.log(JSON.stringify({ success: true, data }, null, 2));
178
+ } else {
179
+ const maxLabelLength = Math.max(...items.map((i) => i.label.length));
180
+ items.forEach((item) => {
181
+ console.log(
182
+ `${chalk2.gray(item.label.padEnd(maxLabelLength))} ${chalk2.white(item.value)}`
183
+ );
184
+ });
185
+ }
186
+ }
187
+ function prettyPrint(data, indent = 0) {
188
+ const prefix = " ".repeat(indent);
189
+ if (Array.isArray(data)) {
190
+ data.forEach((item, index) => {
191
+ console.log(`${prefix}${chalk2.gray(`[${index}]`)}`);
192
+ prettyPrint(item, indent + 1);
193
+ });
194
+ } else if (typeof data === "object" && data !== null) {
195
+ for (const [key, value] of Object.entries(data)) {
196
+ if (typeof value === "object" && value !== null) {
197
+ console.log(`${prefix}${chalk2.gray(key)}:`);
198
+ prettyPrint(value, indent + 1);
199
+ } else {
200
+ console.log(
201
+ `${prefix}${chalk2.gray(key)}: ${chalk2.white(String(value))}`
202
+ );
203
+ }
204
+ }
205
+ } else {
206
+ console.log(`${prefix}${chalk2.white(String(data))}`);
207
+ }
208
+ }
209
+
210
+ // src/commands/config/init.ts
211
+ var configInitCommand = new Command("init").description("Initialize .waniwani config in the current directory").option("--force", "Overwrite existing config").action(async (options, command) => {
212
+ const globalOptions = command.optsWithGlobals();
213
+ const json = globalOptions.json ?? false;
214
+ try {
215
+ const cwd = process.cwd();
216
+ const configPath = join2(cwd, LOCAL_CONFIG_DIR, CONFIG_FILE_NAME);
217
+ if (existsSync2(configPath) && !options.force) {
218
+ throw new CLIError(
219
+ `Config already exists at ${configPath}. Use --force to overwrite.`,
220
+ "CONFIG_EXISTS"
221
+ );
222
+ }
223
+ const result = await initConfigAt(cwd);
224
+ if (json) {
225
+ formatOutput({ created: result.path, config: result.config }, true);
226
+ } else {
227
+ formatSuccess(`Created ${result.path}`, false);
228
+ }
229
+ } catch (error) {
230
+ handleError(error, json);
231
+ process.exit(1);
232
+ }
233
+ });
234
+
235
+ // src/commands/config/index.ts
236
+ var configCommand = new Command2("config").description("Manage WaniWani configuration").addCommand(configInitCommand);
237
+
238
+ // src/commands/dev.ts
239
+ import { relative as relative2 } from "path";
240
+ import chalk3 from "chalk";
241
+ import chokidar from "chokidar";
242
+ import { Command as Command3 } from "commander";
243
+ import ora from "ora";
94
244
 
95
245
  // src/lib/auth.ts
96
- var CONFIG_DIR = join2(homedir2(), ".waniwani");
97
- var AUTH_FILE = join2(CONFIG_DIR, "auth.json");
246
+ import { access, mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
247
+ import { homedir as homedir2 } from "os";
248
+ import { join as join3 } from "path";
249
+ import { z as z2 } from "zod";
250
+ var CONFIG_DIR = join3(homedir2(), ".waniwani");
251
+ var AUTH_FILE = join3(CONFIG_DIR, "auth.json");
98
252
  var AuthStoreSchema = z2.object({
99
253
  accessToken: z2.string().nullable().default(null),
100
254
  refreshToken: z2.string().nullable().default(null),
@@ -196,57 +350,6 @@ var AuthManager = class {
196
350
  };
197
351
  var auth = new AuthManager();
198
352
 
199
- // src/lib/errors.ts
200
- import chalk from "chalk";
201
- import { ZodError } from "zod";
202
- var CLIError = class extends Error {
203
- constructor(message, code, details) {
204
- super(message);
205
- this.code = code;
206
- this.details = details;
207
- this.name = "CLIError";
208
- }
209
- };
210
- var AuthError = class extends CLIError {
211
- constructor(message, details) {
212
- super(message, "AUTH_ERROR", details);
213
- }
214
- };
215
- var SandboxError = class extends CLIError {
216
- constructor(message, details) {
217
- super(message, "SANDBOX_ERROR", details);
218
- }
219
- };
220
- var McpError = class extends CLIError {
221
- constructor(message, details) {
222
- super(message, "MCP_ERROR", details);
223
- }
224
- };
225
- function handleError(error, json) {
226
- if (error instanceof ZodError) {
227
- const message = error.issues.map((e) => `${e.path.join(".")}: ${e.message}`).join(", ");
228
- outputError("VALIDATION_ERROR", `Invalid input: ${message}`, json);
229
- } else if (error instanceof CLIError) {
230
- outputError(error.code, error.message, json, error.details);
231
- } else if (error instanceof Error) {
232
- outputError("UNKNOWN_ERROR", error.message, json);
233
- } else {
234
- outputError("UNKNOWN_ERROR", String(error), json);
235
- }
236
- }
237
- function outputError(code, message, json, details) {
238
- if (json) {
239
- console.error(
240
- JSON.stringify({ success: false, error: { code, message, details } })
241
- );
242
- } else {
243
- console.error(chalk.red(`Error [${code}]:`), message);
244
- if (details) {
245
- console.error(chalk.gray("Details:"), JSON.stringify(details, null, 2));
246
- }
247
- }
248
- }
249
-
250
353
  // src/lib/api.ts
251
354
  var ApiError = class extends CLIError {
252
355
  constructor(message, code, statusCode, details) {
@@ -336,9 +439,9 @@ var api = {
336
439
  };
337
440
 
338
441
  // src/lib/sync.ts
339
- import { existsSync as existsSync2 } from "fs";
442
+ import { existsSync as existsSync3 } from "fs";
340
443
  import { mkdir as mkdir3, readdir, readFile as readFile3, stat, writeFile as writeFile3 } from "fs/promises";
341
- import { dirname, join as join3, relative } from "path";
444
+ import { dirname, join as join4, relative } from "path";
342
445
  import ignore from "ignore";
343
446
 
344
447
  // src/lib/utils.ts
@@ -393,20 +496,20 @@ async function findProjectRoot(startDir) {
393
496
  let current = startDir;
394
497
  const root = dirname(current);
395
498
  while (current !== root) {
396
- if (existsSync2(join3(current, PROJECT_DIR))) {
499
+ if (existsSync3(join4(current, PROJECT_DIR))) {
397
500
  return current;
398
501
  }
399
502
  const parent = dirname(current);
400
503
  if (parent === current) break;
401
504
  current = parent;
402
505
  }
403
- if (existsSync2(join3(current, PROJECT_DIR))) {
506
+ if (existsSync3(join4(current, PROJECT_DIR))) {
404
507
  return current;
405
508
  }
406
509
  return null;
407
510
  }
408
511
  async function loadProjectMcpId(projectRoot) {
409
- const settingsPath = join3(projectRoot, PROJECT_DIR, SETTINGS_FILE);
512
+ const settingsPath = join4(projectRoot, PROJECT_DIR, SETTINGS_FILE);
410
513
  try {
411
514
  const content = await readFile3(settingsPath, "utf-8");
412
515
  const settings = JSON.parse(content);
@@ -434,8 +537,8 @@ var DEFAULT_IGNORE_PATTERNS = [
434
537
  async function loadIgnorePatterns(projectRoot) {
435
538
  const ig = ignore();
436
539
  ig.add(DEFAULT_IGNORE_PATTERNS);
437
- const gitignorePath = join3(projectRoot, ".gitignore");
438
- if (existsSync2(gitignorePath)) {
540
+ const gitignorePath = join4(projectRoot, ".gitignore");
541
+ if (existsSync3(gitignorePath)) {
439
542
  try {
440
543
  const content = await readFile3(gitignorePath, "utf-8");
441
544
  ig.add(content);
@@ -450,7 +553,7 @@ async function collectFiles(projectRoot) {
450
553
  async function walk(dir) {
451
554
  const entries = await readdir(dir, { withFileTypes: true });
452
555
  for (const entry of entries) {
453
- const fullPath = join3(dir, entry.name);
556
+ const fullPath = join4(dir, entry.name);
454
557
  const relativePath = relative(projectRoot, fullPath);
455
558
  if (ig.ignores(relativePath)) {
456
559
  continue;
@@ -480,7 +583,7 @@ async function pullFilesFromSandbox(mcpId, targetDir) {
480
583
  );
481
584
  const writtenFiles = [];
482
585
  for (const file of result.files) {
483
- const localPath = join3(targetDir, file.path);
586
+ const localPath = join4(targetDir, file.path);
484
587
  const dir = dirname(localPath);
485
588
  await mkdir3(dir, { recursive: true });
486
589
  if (file.encoding === "base64") {
@@ -493,9 +596,9 @@ async function pullFilesFromSandbox(mcpId, targetDir) {
493
596
  return { count: writtenFiles.length, files: writtenFiles };
494
597
  }
495
598
  async function collectSingleFile(projectRoot, filePath) {
496
- const fullPath = join3(projectRoot, filePath);
599
+ const fullPath = join4(projectRoot, filePath);
497
600
  const relativePath = relative(projectRoot, fullPath);
498
- if (!existsSync2(fullPath)) {
601
+ if (!existsSync3(fullPath)) {
499
602
  return null;
500
603
  }
501
604
  try {
@@ -518,7 +621,7 @@ async function collectSingleFile(projectRoot, filePath) {
518
621
  // src/commands/dev.ts
519
622
  var BATCH_SIZE = 50;
520
623
  var DEFAULT_DEBOUNCE_MS = 300;
521
- var devCommand = new Command("dev").description("Watch and sync files to MCP sandbox").option("--no-initial-sync", "Skip initial sync of all files").option(
624
+ var devCommand = new Command3("dev").description("Watch and sync files to MCP sandbox").option("--no-initial-sync", "Skip initial sync of all files").option(
522
625
  "--debounce <ms>",
523
626
  "Debounce delay in milliseconds",
524
627
  String(DEFAULT_DEBOUNCE_MS)
@@ -576,7 +679,7 @@ var devCommand = new Command("dev").description("Watch and sync files to MCP san
576
679
  }
577
680
  const file = await collectSingleFile(projectRoot, relativePath);
578
681
  if (!file) {
579
- console.log(chalk2.yellow("Skipped:"), relativePath);
682
+ console.log(chalk3.yellow("Skipped:"), relativePath);
580
683
  return;
581
684
  }
582
685
  try {
@@ -592,17 +695,17 @@ var devCommand = new Command("dev").description("Watch and sync files to MCP san
592
695
  ]
593
696
  }
594
697
  );
595
- console.log(chalk2.green("Synced:"), relativePath);
698
+ console.log(chalk3.green("Synced:"), relativePath);
596
699
  } catch (error) {
597
- console.log(chalk2.red("Failed:"), relativePath);
700
+ console.log(chalk3.red("Failed:"), relativePath);
598
701
  if (globalOptions.verbose) {
599
702
  console.error(error);
600
703
  }
601
704
  }
602
705
  }, debounceMs);
603
706
  console.log();
604
- console.log(chalk2.bold("Watching for changes..."));
605
- console.log(chalk2.dim("Press Ctrl+C to stop"));
707
+ console.log(chalk3.bold("Watching for changes..."));
708
+ console.log(chalk3.dim("Press Ctrl+C to stop"));
606
709
  console.log();
607
710
  const watcher = chokidar.watch(projectRoot, {
608
711
  ignored: (path) => {
@@ -618,11 +721,11 @@ var devCommand = new Command("dev").description("Watch and sync files to MCP san
618
721
  });
619
722
  watcher.on("add", (path) => syncFile(path)).on("change", (path) => syncFile(path)).on("unlink", (path) => {
620
723
  const relativePath = relative2(projectRoot, path);
621
- console.log(chalk2.yellow("Deleted (local only):"), relativePath);
724
+ console.log(chalk3.yellow("Deleted (local only):"), relativePath);
622
725
  });
623
726
  const cleanup = () => {
624
727
  console.log();
625
- console.log(chalk2.dim("Stopping watcher..."));
728
+ console.log(chalk3.dim("Stopping watcher..."));
626
729
  watcher.close().then(() => {
627
730
  process.exit(0);
628
731
  });
@@ -636,95 +739,32 @@ var devCommand = new Command("dev").description("Watch and sync files to MCP san
636
739
  });
637
740
 
638
741
  // src/commands/init.ts
639
- import { existsSync as existsSync3 } from "fs";
640
- import { mkdir as mkdir4, writeFile as writeFile4 } from "fs/promises";
641
- import { join as join4 } from "path";
642
- import { Command as Command2 } from "commander";
742
+ import { existsSync as existsSync4 } from "fs";
743
+ import { mkdir as mkdir4, readFile as readFile4 } from "fs/promises";
744
+ import { join as join5 } from "path";
745
+ import { Command as Command4 } from "commander";
643
746
  import ora2 from "ora";
644
-
645
- // src/lib/output.ts
646
- import chalk3 from "chalk";
647
- function formatOutput(data, json) {
648
- if (json) {
649
- console.log(JSON.stringify({ success: true, data }, null, 2));
650
- } else {
651
- prettyPrint(data);
652
- }
653
- }
654
- function formatSuccess(message, json) {
655
- if (json) {
656
- console.log(JSON.stringify({ success: true, message }));
657
- } else {
658
- console.log(chalk3.green("\u2713"), message);
659
- }
660
- }
661
- function formatTable(headers, rows, json) {
662
- if (json) {
663
- const data = rows.map(
664
- (row) => Object.fromEntries(headers.map((header, i) => [header, row[i]]))
665
- );
666
- console.log(JSON.stringify({ success: true, data }, null, 2));
667
- } else {
668
- const colWidths = headers.map(
669
- (h, i) => Math.max(h.length, ...rows.map((r) => (r[i] || "").length))
670
- );
671
- const separator = colWidths.map((w) => "-".repeat(w + 2)).join("+");
672
- const formatRow = (row) => row.map((cell, i) => ` ${(cell || "").padEnd(colWidths[i])} `).join("|");
673
- console.log(chalk3.cyan(formatRow(headers)));
674
- console.log(separator);
675
- for (const row of rows) {
676
- console.log(formatRow(row));
677
- }
678
- }
679
- }
680
- function formatList(items, json) {
681
- if (json) {
682
- const data = Object.fromEntries(
683
- items.map((item) => [item.label, item.value])
684
- );
685
- console.log(JSON.stringify({ success: true, data }, null, 2));
686
- } else {
687
- const maxLabelLength = Math.max(...items.map((i) => i.label.length));
688
- items.forEach((item) => {
689
- console.log(
690
- `${chalk3.gray(item.label.padEnd(maxLabelLength))} ${chalk3.white(item.value)}`
691
- );
692
- });
747
+ async function loadParentConfig(cwd) {
748
+ const parentConfigPath = join5(cwd, LOCAL_CONFIG_DIR, CONFIG_FILE_NAME);
749
+ if (!existsSync4(parentConfigPath)) {
750
+ return null;
693
751
  }
694
- }
695
- function prettyPrint(data, indent = 0) {
696
- const prefix = " ".repeat(indent);
697
- if (Array.isArray(data)) {
698
- data.forEach((item, index) => {
699
- console.log(`${prefix}${chalk3.gray(`[${index}]`)}`);
700
- prettyPrint(item, indent + 1);
701
- });
702
- } else if (typeof data === "object" && data !== null) {
703
- for (const [key, value] of Object.entries(data)) {
704
- if (typeof value === "object" && value !== null) {
705
- console.log(`${prefix}${chalk3.gray(key)}:`);
706
- prettyPrint(value, indent + 1);
707
- } else {
708
- console.log(
709
- `${prefix}${chalk3.gray(key)}: ${chalk3.white(String(value))}`
710
- );
711
- }
712
- }
713
- } else {
714
- console.log(`${prefix}${chalk3.white(String(data))}`);
752
+ try {
753
+ const content = await readFile4(parentConfigPath, "utf-8");
754
+ const config2 = JSON.parse(content);
755
+ const { mcpId: _, ...rest } = config2;
756
+ return rest;
757
+ } catch {
758
+ return null;
715
759
  }
716
760
  }
717
-
718
- // src/commands/init.ts
719
- var PROJECT_CONFIG_DIR = ".waniwani";
720
- var PROJECT_CONFIG_FILE = "settings.json";
721
- var initCommand = new Command2("init").description("Create a new MCP project from template").argument("<name>", "Name for the MCP project").action(async (name, _, command) => {
761
+ var initCommand = new Command4("init").description("Create a new MCP project from template").argument("<name>", "Name for the MCP project").action(async (name, _, command) => {
722
762
  const globalOptions = command.optsWithGlobals();
723
763
  const json = globalOptions.json ?? false;
724
764
  try {
725
765
  const cwd = process.cwd();
726
- const projectDir = join4(cwd, name);
727
- if (existsSync3(projectDir)) {
766
+ const projectDir = join5(cwd, name);
767
+ if (existsSync4(projectDir)) {
728
768
  if (json) {
729
769
  formatOutput(
730
770
  {
@@ -746,21 +786,12 @@ var initCommand = new Command2("init").description("Create a new MCP project fro
746
786
  await mkdir4(projectDir, { recursive: true });
747
787
  await pullFilesFromSandbox(result.id, projectDir);
748
788
  spinner.text = "Setting up project config...";
749
- const configDir = join4(projectDir, PROJECT_CONFIG_DIR);
750
- const configPath = join4(configDir, PROJECT_CONFIG_FILE);
751
- await mkdir4(configDir, { recursive: true });
752
- const projectConfig = {
753
- mcpId: result.id,
754
- defaults: {
755
- model: "claude-sonnet-4-20250514",
756
- maxSteps: 10
757
- }
758
- };
759
- await writeFile4(
760
- configPath,
761
- JSON.stringify(projectConfig, null, " "),
762
- "utf-8"
763
- );
789
+ const parentConfig = await loadParentConfig(cwd);
790
+ await initConfigAt(projectDir, {
791
+ ...parentConfig,
792
+ mcpId: result.id
793
+ // Always use the new sandbox's mcpId
794
+ });
764
795
  spinner.succeed("MCP project created");
765
796
  if (json) {
766
797
  formatOutput(
@@ -797,7 +828,7 @@ var initCommand = new Command2("init").description("Create a new MCP project fro
797
828
  import { spawn } from "child_process";
798
829
  import { createServer } from "http";
799
830
  import chalk4 from "chalk";
800
- import { Command as Command3 } from "commander";
831
+ import { Command as Command5 } from "commander";
801
832
  import ora3 from "ora";
802
833
  var CALLBACK_PORT = 54321;
803
834
  var CALLBACK_URL = `http://localhost:${CALLBACK_PORT}/callback`;
@@ -1073,7 +1104,7 @@ async function exchangeCodeForToken(code, codeVerifier, clientId, resource) {
1073
1104
  }
1074
1105
  return response.json();
1075
1106
  }
1076
- var loginCommand = new Command3("login").description("Log in to WaniWani").option("--no-browser", "Don't open the browser automatically").action(async (options, command) => {
1107
+ var loginCommand = new Command5("login").description("Log in to WaniWani").option("--no-browser", "Don't open the browser automatically").action(async (options, command) => {
1077
1108
  const globalOptions = command.optsWithGlobals();
1078
1109
  const json = globalOptions.json ?? false;
1079
1110
  try {
@@ -1178,8 +1209,8 @@ var loginCommand = new Command3("login").description("Log in to WaniWani").optio
1178
1209
  });
1179
1210
 
1180
1211
  // src/commands/logout.ts
1181
- import { Command as Command4 } from "commander";
1182
- var logoutCommand = new Command4("logout").description("Log out from WaniWani").action(async (_, command) => {
1212
+ import { Command as Command6 } from "commander";
1213
+ var logoutCommand = new Command6("logout").description("Log out from WaniWani").action(async (_, command) => {
1183
1214
  const globalOptions = command.optsWithGlobals();
1184
1215
  const json = globalOptions.json ?? false;
1185
1216
  try {
@@ -1204,12 +1235,12 @@ var logoutCommand = new Command4("logout").description("Log out from WaniWani").
1204
1235
  });
1205
1236
 
1206
1237
  // src/commands/mcp/index.ts
1207
- import { Command as Command19 } from "commander";
1238
+ import { Command as Command20 } from "commander";
1208
1239
 
1209
1240
  // src/commands/mcp/delete.ts
1210
- import { Command as Command5 } from "commander";
1241
+ import { Command as Command7 } from "commander";
1211
1242
  import ora4 from "ora";
1212
- var deleteCommand = new Command5("delete").description("Delete the MCP sandbox").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
1243
+ var deleteCommand = new Command7("delete").description("Delete the MCP sandbox").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
1213
1244
  const globalOptions = command.optsWithGlobals();
1214
1245
  const json = globalOptions.json ?? false;
1215
1246
  try {
@@ -1238,9 +1269,9 @@ var deleteCommand = new Command5("delete").description("Delete the MCP sandbox")
1238
1269
  });
1239
1270
 
1240
1271
  // src/commands/mcp/deploy.ts
1241
- import { Command as Command6 } from "commander";
1272
+ import { Command as Command8 } from "commander";
1242
1273
  import ora5 from "ora";
1243
- var deployCommand = new Command6("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) => {
1274
+ var deployCommand = new Command8("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) => {
1244
1275
  const globalOptions = command.optsWithGlobals();
1245
1276
  const json = globalOptions.json ?? false;
1246
1277
  try {
@@ -1285,13 +1316,13 @@ var deployCommand = new Command6("deploy").description("Deploy MCP server to Git
1285
1316
  });
1286
1317
 
1287
1318
  // src/commands/mcp/file/index.ts
1288
- import { Command as Command10 } from "commander";
1319
+ import { Command as Command12 } from "commander";
1289
1320
 
1290
1321
  // src/commands/mcp/file/list.ts
1291
1322
  import chalk5 from "chalk";
1292
- import { Command as Command7 } from "commander";
1323
+ import { Command as Command9 } from "commander";
1293
1324
  import ora6 from "ora";
1294
- var listCommand = new Command7("list").description("List files in the MCP sandbox").argument("[path]", "Directory path (defaults to /app)", "/app").option("--mcp-id <id>", "Specific MCP ID").action(async (path, options, command) => {
1325
+ var listCommand = new Command9("list").description("List files in the MCP sandbox").argument("[path]", "Directory path (defaults to /app)", "/app").option("--mcp-id <id>", "Specific MCP ID").action(async (path, options, command) => {
1295
1326
  const globalOptions = command.optsWithGlobals();
1296
1327
  const json = globalOptions.json ?? false;
1297
1328
  try {
@@ -1340,10 +1371,10 @@ function formatSize(bytes) {
1340
1371
  }
1341
1372
 
1342
1373
  // src/commands/mcp/file/read.ts
1343
- import { writeFile as writeFile5 } from "fs/promises";
1344
- import { Command as Command8 } from "commander";
1374
+ import { writeFile as writeFile4 } from "fs/promises";
1375
+ import { Command as Command10 } from "commander";
1345
1376
  import ora7 from "ora";
1346
- var readCommand = new Command8("read").description("Read a file from the MCP sandbox").argument("<path>", "Path in sandbox (e.g., /app/src/index.ts)").option("--mcp-id <id>", "Specific MCP ID").option("--output <file>", "Write to local file instead of stdout").option("--base64", "Output as base64 (for binary files)").action(async (path, options, command) => {
1377
+ var readCommand = new Command10("read").description("Read a file from the MCP sandbox").argument("<path>", "Path in sandbox (e.g., /app/src/index.ts)").option("--mcp-id <id>", "Specific MCP ID").option("--output <file>", "Write to local file instead of stdout").option("--base64", "Output as base64 (for binary files)").action(async (path, options, command) => {
1347
1378
  const globalOptions = command.optsWithGlobals();
1348
1379
  const json = globalOptions.json ?? false;
1349
1380
  try {
@@ -1367,7 +1398,7 @@ var readCommand = new Command8("read").description("Read a file from the MCP san
1367
1398
  }
1368
1399
  if (options.output) {
1369
1400
  const buffer = result.encoding === "base64" ? Buffer.from(result.content, "base64") : Buffer.from(result.content, "utf8");
1370
- await writeFile5(options.output, buffer);
1401
+ await writeFile4(options.output, buffer);
1371
1402
  if (json) {
1372
1403
  formatOutput({ path, savedTo: options.output }, true);
1373
1404
  } else {
@@ -1388,10 +1419,10 @@ var readCommand = new Command8("read").description("Read a file from the MCP san
1388
1419
  });
1389
1420
 
1390
1421
  // src/commands/mcp/file/write.ts
1391
- import { readFile as readFile4 } from "fs/promises";
1392
- import { Command as Command9 } from "commander";
1422
+ import { readFile as readFile5 } from "fs/promises";
1423
+ import { Command as Command11 } from "commander";
1393
1424
  import ora8 from "ora";
1394
- var writeCommand = new Command9("write").description("Write a file to the MCP sandbox").argument("<path>", "Path in sandbox (e.g., /app/src/index.ts)").option("--mcp-id <id>", "Specific MCP ID").option("--content <content>", "Content to write").option("--file <localFile>", "Local file to upload").option("--base64", "Treat content as base64 encoded").action(async (path, options, command) => {
1425
+ var writeCommand = new Command11("write").description("Write a file to the MCP sandbox").argument("<path>", "Path in sandbox (e.g., /app/src/index.ts)").option("--mcp-id <id>", "Specific MCP ID").option("--content <content>", "Content to write").option("--file <localFile>", "Local file to upload").option("--base64", "Treat content as base64 encoded").action(async (path, options, command) => {
1395
1426
  const globalOptions = command.optsWithGlobals();
1396
1427
  const json = globalOptions.json ?? false;
1397
1428
  try {
@@ -1412,7 +1443,7 @@ var writeCommand = new Command9("write").description("Write a file to the MCP sa
1412
1443
  encoding = "base64";
1413
1444
  }
1414
1445
  } else if (options.file) {
1415
- const fileBuffer = await readFile4(options.file);
1446
+ const fileBuffer = await readFile5(options.file);
1416
1447
  if (options.base64) {
1417
1448
  content = fileBuffer.toString("base64");
1418
1449
  encoding = "base64";
@@ -1445,13 +1476,13 @@ var writeCommand = new Command9("write").description("Write a file to the MCP sa
1445
1476
  });
1446
1477
 
1447
1478
  // src/commands/mcp/file/index.ts
1448
- var fileCommand = new Command10("file").description("File operations in MCP sandbox").addCommand(readCommand).addCommand(writeCommand).addCommand(listCommand);
1479
+ var fileCommand = new Command12("file").description("File operations in MCP sandbox").addCommand(readCommand).addCommand(writeCommand).addCommand(listCommand);
1449
1480
 
1450
1481
  // src/commands/mcp/list.ts
1451
1482
  import chalk6 from "chalk";
1452
- import { Command as Command11 } from "commander";
1483
+ import { Command as Command13 } from "commander";
1453
1484
  import ora9 from "ora";
1454
- var listCommand2 = new Command11("list").description("List all MCPs in your organization").option("--all", "Include stopped/expired MCPs").action(async (options, command) => {
1485
+ var listCommand2 = new Command13("list").description("List all MCPs in your organization").option("--all", "Include stopped/expired MCPs").action(async (options, command) => {
1455
1486
  const globalOptions = command.optsWithGlobals();
1456
1487
  const json = globalOptions.json ?? false;
1457
1488
  try {
@@ -1509,9 +1540,9 @@ var listCommand2 = new Command11("list").description("List all MCPs in your orga
1509
1540
 
1510
1541
  // src/commands/mcp/logs.ts
1511
1542
  import chalk7 from "chalk";
1512
- import { Command as Command12 } from "commander";
1543
+ import { Command as Command14 } from "commander";
1513
1544
  import ora10 from "ora";
1514
- var logsCommand = new Command12("logs").description("Stream logs from the MCP server").argument("[cmdId]", "Command ID (defaults to running server)").option("--mcp-id <id>", "Specific MCP ID").option("-f, --follow", "Keep streaming logs (default)", true).option("--no-follow", "Fetch logs and exit").action(async (cmdIdArg, options, command) => {
1545
+ var logsCommand = new Command14("logs").description("Stream logs from the MCP server").argument("[cmdId]", "Command ID (defaults to running server)").option("--mcp-id <id>", "Specific MCP ID").option("-f, --follow", "Keep streaming logs (default)", true).option("--no-follow", "Fetch logs and exit").action(async (cmdIdArg, options, command) => {
1515
1546
  const globalOptions = command.optsWithGlobals();
1516
1547
  const json = globalOptions.json ?? false;
1517
1548
  let reader;
@@ -1659,9 +1690,9 @@ Error: ${event.error}`));
1659
1690
 
1660
1691
  // src/commands/mcp/run-command.ts
1661
1692
  import chalk8 from "chalk";
1662
- import { Command as Command13 } from "commander";
1693
+ import { Command as Command15 } from "commander";
1663
1694
  import ora11 from "ora";
1664
- var runCommandCommand = new Command13("run-command").description("Run a command in the MCP sandbox").argument("<command>", "Command to run").argument("[args...]", "Command arguments").option("--mcp-id <id>", "Specific MCP ID").option("--cwd <path>", "Working directory").option(
1695
+ var runCommandCommand = new Command15("run-command").description("Run a command in the MCP sandbox").argument("<command>", "Command to run").argument("[args...]", "Command arguments").option("--mcp-id <id>", "Specific MCP ID").option("--cwd <path>", "Working directory").option(
1665
1696
  "--timeout <ms>",
1666
1697
  "Command timeout in milliseconds (default: 30000, max: 300000)"
1667
1698
  ).action(async (cmd, args, options, command) => {
@@ -1725,9 +1756,9 @@ var runCommandCommand = new Command13("run-command").description("Run a command
1725
1756
 
1726
1757
  // src/commands/mcp/start.ts
1727
1758
  import chalk9 from "chalk";
1728
- import { Command as Command14 } from "commander";
1759
+ import { Command as Command16 } from "commander";
1729
1760
  import ora12 from "ora";
1730
- var startCommand = new Command14("start").description("Start the MCP server (npm run dev)").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
1761
+ var startCommand = new Command16("start").description("Start the MCP server (npm run dev)").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
1731
1762
  const globalOptions = command.optsWithGlobals();
1732
1763
  const json = globalOptions.json ?? false;
1733
1764
  try {
@@ -1758,6 +1789,11 @@ var startCommand = new Command14("start").description("Start the MCP server (npm
1758
1789
  false
1759
1790
  );
1760
1791
  console.log();
1792
+ console.log(chalk9.bold("Test with MCP Inspector:"));
1793
+ console.log(
1794
+ ` npx @modelcontextprotocol/inspector --url ${result.previewUrl}`
1795
+ );
1796
+ console.log();
1761
1797
  console.log(
1762
1798
  chalk9.gray("Run 'waniwani mcp logs' to stream server output")
1763
1799
  );
@@ -1770,9 +1806,9 @@ var startCommand = new Command14("start").description("Start the MCP server (npm
1770
1806
 
1771
1807
  // src/commands/mcp/status.ts
1772
1808
  import chalk10 from "chalk";
1773
- import { Command as Command15 } from "commander";
1809
+ import { Command as Command17 } from "commander";
1774
1810
  import ora13 from "ora";
1775
- var statusCommand = new Command15("status").description("Show current MCP sandbox status").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
1811
+ var statusCommand = new Command17("status").description("Show current MCP sandbox status").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
1776
1812
  const globalOptions = command.optsWithGlobals();
1777
1813
  const json = globalOptions.json ?? false;
1778
1814
  try {
@@ -1828,9 +1864,9 @@ var statusCommand = new Command15("status").description("Show current MCP sandbo
1828
1864
  });
1829
1865
 
1830
1866
  // src/commands/mcp/stop.ts
1831
- import { Command as Command16 } from "commander";
1867
+ import { Command as Command18 } from "commander";
1832
1868
  import ora14 from "ora";
1833
- var stopCommand = new Command16("stop").description("Stop the MCP server process").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
1869
+ var stopCommand = new Command18("stop").description("Stop the MCP server process").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
1834
1870
  const globalOptions = command.optsWithGlobals();
1835
1871
  const json = globalOptions.json ?? false;
1836
1872
  try {
@@ -1864,105 +1900,14 @@ var stopCommand = new Command16("stop").description("Stop the MCP server process
1864
1900
  }
1865
1901
  });
1866
1902
 
1867
- // src/commands/mcp/test.ts
1868
- import chalk11 from "chalk";
1869
- import { Command as Command17 } from "commander";
1870
- import ora15 from "ora";
1871
- var testCommand = new Command17("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(
1872
- async (tool, args, options, command) => {
1873
- const globalOptions = command.optsWithGlobals();
1874
- const json = globalOptions.json ?? false;
1875
- try {
1876
- let mcpId = options.mcpId;
1877
- if (!mcpId) {
1878
- mcpId = await config.getMcpId();
1879
- if (!mcpId) {
1880
- throw new McpError(
1881
- "No active MCP. Run 'waniwani mcp create <name>' or 'waniwani mcp use <name>'."
1882
- );
1883
- }
1884
- }
1885
- if (!tool) {
1886
- const spinner = ora15("Fetching available tools...").start();
1887
- const result = await api.post(
1888
- `/api/mcp/sandboxes/${mcpId}/test`,
1889
- { action: "list" }
1890
- );
1891
- spinner.stop();
1892
- const tools = result.tools;
1893
- if (json) {
1894
- formatOutput({ tools }, true);
1895
- } else {
1896
- if (tools.length === 0) {
1897
- console.log("No tools available.");
1898
- } else {
1899
- console.log(chalk11.bold("\nAvailable Tools:\n"));
1900
- formatTable(
1901
- ["Name", "Description"],
1902
- tools.map((t) => [t.name, t.description || "No description"]),
1903
- false
1904
- );
1905
- console.log(
1906
- `
1907
- Test a tool: waniwani mcp test <tool-name> '{"arg": "value"}'`
1908
- );
1909
- }
1910
- }
1911
- } else {
1912
- let toolArgs = {};
1913
- if (args.length > 0) {
1914
- try {
1915
- toolArgs = JSON.parse(args.join(" "));
1916
- } catch {
1917
- throw new SandboxError(
1918
- `Invalid JSON arguments. Expected format: '{"key": "value"}'`
1919
- );
1920
- }
1921
- }
1922
- const spinner = ora15(`Calling tool "${tool}"...`).start();
1923
- const startTime = Date.now();
1924
- const result = await api.post(
1925
- `/api/mcp/sandboxes/${mcpId}/test`,
1926
- {
1927
- action: "call",
1928
- tool,
1929
- args: toolArgs
1930
- }
1931
- );
1932
- const duration = result.duration || Date.now() - startTime;
1933
- spinner.stop();
1934
- const output = {
1935
- tool,
1936
- input: toolArgs,
1937
- result: result.result,
1938
- duration
1939
- };
1940
- if (json) {
1941
- formatOutput(output, true);
1942
- } else {
1943
- console.log(chalk11.bold("\nTool Result:\n"));
1944
- console.log(chalk11.gray("Tool:"), tool);
1945
- console.log(chalk11.gray("Input:"), JSON.stringify(toolArgs));
1946
- console.log(chalk11.gray("Duration:"), `${duration}ms`);
1947
- console.log(chalk11.gray("Result:"));
1948
- console.log(JSON.stringify(result.result, null, 2));
1949
- }
1950
- }
1951
- } catch (error) {
1952
- handleError(error, json);
1953
- process.exit(1);
1954
- }
1955
- }
1956
- );
1957
-
1958
1903
  // src/commands/mcp/use.ts
1959
- import { Command as Command18 } from "commander";
1960
- import ora16 from "ora";
1961
- var useCommand = new Command18("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) => {
1904
+ import { Command as Command19 } from "commander";
1905
+ import ora15 from "ora";
1906
+ var useCommand = new Command19("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) => {
1962
1907
  const globalOptions = command.optsWithGlobals();
1963
1908
  const json = globalOptions.json ?? false;
1964
1909
  try {
1965
- const spinner = ora16("Fetching MCPs...").start();
1910
+ const spinner = ora15("Fetching MCPs...").start();
1966
1911
  const mcps = await api.get("/api/admin/mcps");
1967
1912
  spinner.stop();
1968
1913
  const mcp = mcps.find((m) => m.name === name);
@@ -1998,20 +1943,20 @@ var useCommand = new Command18("use").description("Select an MCP to use for subs
1998
1943
  });
1999
1944
 
2000
1945
  // src/commands/mcp/index.ts
2001
- var mcpCommand = new Command19("mcp").description("MCP sandbox management commands").addCommand(listCommand2).addCommand(useCommand).addCommand(statusCommand).addCommand(startCommand).addCommand(stopCommand).addCommand(logsCommand).addCommand(deleteCommand).addCommand(testCommand).addCommand(deployCommand).addCommand(fileCommand).addCommand(runCommandCommand);
1946
+ var mcpCommand = new Command20("mcp").description("MCP sandbox management commands").addCommand(listCommand2).addCommand(useCommand).addCommand(statusCommand).addCommand(startCommand).addCommand(stopCommand).addCommand(logsCommand).addCommand(deleteCommand).addCommand(deployCommand).addCommand(fileCommand).addCommand(runCommandCommand);
2002
1947
 
2003
1948
  // src/commands/org/index.ts
2004
- import { Command as Command22 } from "commander";
1949
+ import { Command as Command23 } from "commander";
2005
1950
 
2006
1951
  // src/commands/org/list.ts
2007
- import chalk12 from "chalk";
2008
- import { Command as Command20 } from "commander";
2009
- import ora17 from "ora";
2010
- var listCommand3 = new Command20("list").description("List your organizations").action(async (_, command) => {
1952
+ import chalk11 from "chalk";
1953
+ import { Command as Command21 } from "commander";
1954
+ import ora16 from "ora";
1955
+ var listCommand3 = new Command21("list").description("List your organizations").action(async (_, command) => {
2011
1956
  const globalOptions = command.optsWithGlobals();
2012
1957
  const json = globalOptions.json ?? false;
2013
1958
  try {
2014
- const spinner = ora17("Fetching organizations...").start();
1959
+ const spinner = ora16("Fetching organizations...").start();
2015
1960
  const result = await api.get("/api/oauth/orgs");
2016
1961
  spinner.stop();
2017
1962
  const { orgs, activeOrgId } = result;
@@ -2031,11 +1976,11 @@ var listCommand3 = new Command20("list").description("List your organizations").
2031
1976
  console.log("No organizations found.");
2032
1977
  return;
2033
1978
  }
2034
- console.log(chalk12.bold("\nOrganizations:\n"));
1979
+ console.log(chalk11.bold("\nOrganizations:\n"));
2035
1980
  const rows = orgs.map((o) => {
2036
1981
  const isActive = o.id === activeOrgId;
2037
1982
  return [
2038
- isActive ? chalk12.cyan(`* ${o.name}`) : ` ${o.name}`,
1983
+ isActive ? chalk11.cyan(`* ${o.name}`) : ` ${o.name}`,
2039
1984
  o.slug,
2040
1985
  o.role
2041
1986
  ];
@@ -2045,7 +1990,7 @@ var listCommand3 = new Command20("list").description("List your organizations").
2045
1990
  if (activeOrgId) {
2046
1991
  const activeOrg = orgs.find((o) => o.id === activeOrgId);
2047
1992
  if (activeOrg) {
2048
- console.log(`Active organization: ${chalk12.cyan(activeOrg.name)}`);
1993
+ console.log(`Active organization: ${chalk11.cyan(activeOrg.name)}`);
2049
1994
  }
2050
1995
  }
2051
1996
  console.log("\nSwitch organization: waniwani org switch <name>");
@@ -2057,13 +2002,13 @@ var listCommand3 = new Command20("list").description("List your organizations").
2057
2002
  });
2058
2003
 
2059
2004
  // src/commands/org/switch.ts
2060
- import { Command as Command21 } from "commander";
2061
- import ora18 from "ora";
2062
- var switchCommand = new Command21("switch").description("Switch to a different organization").argument("<name>", "Name or slug of the organization to switch to").action(async (name, _, command) => {
2005
+ import { Command as Command22 } from "commander";
2006
+ import ora17 from "ora";
2007
+ var switchCommand = new Command22("switch").description("Switch to a different organization").argument("<name>", "Name or slug of the organization to switch to").action(async (name, _, command) => {
2063
2008
  const globalOptions = command.optsWithGlobals();
2064
2009
  const json = globalOptions.json ?? false;
2065
2010
  try {
2066
- const spinner = ora18("Fetching organizations...").start();
2011
+ const spinner = ora17("Fetching organizations...").start();
2067
2012
  const { orgs } = await api.get("/api/oauth/orgs");
2068
2013
  const org = orgs.find((o) => o.name === name || o.slug === name);
2069
2014
  if (!org) {
@@ -2096,14 +2041,14 @@ var switchCommand = new Command21("switch").description("Switch to a different o
2096
2041
  });
2097
2042
 
2098
2043
  // src/commands/org/index.ts
2099
- var orgCommand = new Command22("org").description("Organization management commands").addCommand(listCommand3).addCommand(switchCommand);
2044
+ var orgCommand = new Command23("org").description("Organization management commands").addCommand(listCommand3).addCommand(switchCommand);
2100
2045
 
2101
2046
  // src/commands/push.ts
2102
- import chalk13 from "chalk";
2103
- import { Command as Command23 } from "commander";
2104
- import ora19 from "ora";
2047
+ import chalk12 from "chalk";
2048
+ import { Command as Command24 } from "commander";
2049
+ import ora18 from "ora";
2105
2050
  var BATCH_SIZE2 = 50;
2106
- var pushCommand = new Command23("push").description("Sync local files to MCP sandbox").option("--dry-run", "Show what would be synced without uploading").action(async (options, command) => {
2051
+ var pushCommand = new Command24("push").description("Sync local files to MCP sandbox").option("--dry-run", "Show what would be synced without uploading").action(async (options, command) => {
2107
2052
  const globalOptions = command.optsWithGlobals();
2108
2053
  const json = globalOptions.json ?? false;
2109
2054
  try {
@@ -2122,7 +2067,7 @@ var pushCommand = new Command23("push").description("Sync local files to MCP san
2122
2067
  "NO_MCP_ID"
2123
2068
  );
2124
2069
  }
2125
- const spinner = ora19("Collecting files...").start();
2070
+ const spinner = ora18("Collecting files...").start();
2126
2071
  const files = await collectFiles(projectRoot);
2127
2072
  if (files.length === 0) {
2128
2073
  spinner.info("No files to sync");
@@ -2135,7 +2080,7 @@ var pushCommand = new Command23("push").description("Sync local files to MCP san
2135
2080
  if (options.dryRun) {
2136
2081
  spinner.stop();
2137
2082
  console.log();
2138
- console.log(chalk13.bold("Files that would be synced:"));
2083
+ console.log(chalk12.bold("Files that would be synced:"));
2139
2084
  for (const file of files) {
2140
2085
  console.log(` ${file.path}`);
2141
2086
  }
@@ -2179,162 +2124,6 @@ var pushCommand = new Command23("push").description("Sync local files to MCP san
2179
2124
  }
2180
2125
  });
2181
2126
 
2182
- // src/commands/task.ts
2183
- import chalk14 from "chalk";
2184
- import { Command as Command24 } from "commander";
2185
- import ora20 from "ora";
2186
- var taskCommand = new Command24("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) => {
2187
- const globalOptions = command.optsWithGlobals();
2188
- const json = globalOptions.json ?? false;
2189
- try {
2190
- let mcpId = options.mcpId;
2191
- if (!mcpId) {
2192
- mcpId = await config.getMcpId();
2193
- if (!mcpId) {
2194
- throw new McpError(
2195
- "No active MCP. Run 'waniwani init' then 'waniwani mcp use <name>'."
2196
- );
2197
- }
2198
- }
2199
- const token = await auth.getAccessToken();
2200
- if (!token) {
2201
- throw new AuthError(
2202
- "Not logged in. Run 'waniwani login' to authenticate."
2203
- );
2204
- }
2205
- const defaults = await config.getDefaults();
2206
- const model = options.model ?? defaults.model;
2207
- const maxSteps = options.maxSteps ? Number.parseInt(options.maxSteps, 10) : defaults.maxSteps;
2208
- if (!json) {
2209
- console.log();
2210
- console.log(chalk14.bold("Task:"), prompt);
2211
- console.log();
2212
- }
2213
- const spinner = ora20("Starting task...").start();
2214
- const baseUrl = await api.getBaseUrl();
2215
- const response = await fetch(
2216
- `${baseUrl}/api/mcp/sandboxes/${mcpId}/task`,
2217
- {
2218
- method: "POST",
2219
- headers: {
2220
- "Content-Type": "application/json",
2221
- Authorization: `Bearer ${token}`,
2222
- Accept: "text/event-stream"
2223
- },
2224
- body: JSON.stringify({
2225
- prompt,
2226
- model,
2227
- maxSteps
2228
- })
2229
- }
2230
- );
2231
- if (!response.ok) {
2232
- const error = await response.json().catch(() => ({ message: response.statusText }));
2233
- spinner.fail("Task failed");
2234
- throw new Error(
2235
- error.message || `Request failed with status ${response.status}`
2236
- );
2237
- }
2238
- spinner.stop();
2239
- const steps = [];
2240
- let stepCount = 0;
2241
- let maxStepsReached = false;
2242
- const reader = response.body?.getReader();
2243
- if (!reader) {
2244
- throw new Error("No response body");
2245
- }
2246
- const decoder = new TextDecoder();
2247
- let buffer = "";
2248
- while (true) {
2249
- const { done, value } = await reader.read();
2250
- if (done) break;
2251
- buffer += decoder.decode(value, { stream: true });
2252
- const lines = buffer.split("\n");
2253
- buffer = lines.pop() || "";
2254
- for (const line of lines) {
2255
- if (line.startsWith("event: ")) {
2256
- continue;
2257
- }
2258
- if (line.startsWith("data: ")) {
2259
- const data = line.slice(6);
2260
- if (!data || data === "[DONE]") continue;
2261
- try {
2262
- const parsed = JSON.parse(data);
2263
- if (parsed.type === "text") {
2264
- const event = parsed;
2265
- steps.push({ type: "text", text: event.content });
2266
- if (!json && event.content) {
2267
- console.log(chalk14.white(event.content));
2268
- }
2269
- } else if (parsed.type === "tool_call") {
2270
- const event = parsed;
2271
- steps.push({
2272
- type: "tool_call",
2273
- tool: event.tool,
2274
- input: event.input,
2275
- output: event.output
2276
- });
2277
- if (!json) {
2278
- console.log(chalk14.cyan(`> Using tool: ${event.tool}`));
2279
- if (event.input?.command) {
2280
- console.log(chalk14.gray(` $ ${event.input.command}`));
2281
- }
2282
- if (event.output) {
2283
- const outputLines = event.output.split("\n");
2284
- if (outputLines.length > 10) {
2285
- console.log(
2286
- chalk14.gray(outputLines.slice(0, 5).join("\n"))
2287
- );
2288
- console.log(
2289
- chalk14.gray(
2290
- ` ... (${outputLines.length - 10} more lines)`
2291
- )
2292
- );
2293
- console.log(chalk14.gray(outputLines.slice(-5).join("\n")));
2294
- } else {
2295
- console.log(chalk14.gray(event.output));
2296
- }
2297
- }
2298
- console.log();
2299
- }
2300
- } else if (parsed.success !== void 0) {
2301
- const doneEvent = parsed;
2302
- stepCount = doneEvent.stepCount;
2303
- maxStepsReached = doneEvent.maxStepsReached || false;
2304
- }
2305
- } catch {
2306
- }
2307
- }
2308
- }
2309
- }
2310
- const result = {
2311
- success: true,
2312
- steps,
2313
- stepCount,
2314
- maxStepsReached
2315
- };
2316
- const finalStepCount = stepCount ?? steps.length;
2317
- if (json) {
2318
- formatOutput({ ...result, stepCount: finalStepCount }, true);
2319
- } else {
2320
- console.log();
2321
- console.log(
2322
- chalk14.green("\u2713"),
2323
- `Task completed in ${finalStepCount} steps.`
2324
- );
2325
- if (maxStepsReached) {
2326
- console.log(
2327
- chalk14.yellow("\u26A0"),
2328
- "Maximum steps reached. Task may be incomplete."
2329
- );
2330
- }
2331
- }
2332
- } catch (error) {
2333
- handleError(error, json);
2334
- process.exit(1);
2335
- }
2336
- });
2337
-
2338
2127
  // src/cli.ts
2339
2128
  var version = "0.1.0";
2340
2129
  var program = new Command25().name("waniwani").description("WaniWani CLI for MCP development workflow").version(version).option("--json", "Output results as JSON").option("--verbose", "Enable verbose logging");
@@ -2344,8 +2133,8 @@ program.addCommand(initCommand);
2344
2133
  program.addCommand(pushCommand);
2345
2134
  program.addCommand(devCommand);
2346
2135
  program.addCommand(mcpCommand);
2347
- program.addCommand(taskCommand);
2348
2136
  program.addCommand(orgCommand);
2137
+ program.addCommand(configCommand);
2349
2138
 
2350
2139
  // src/index.ts
2351
2140
  program.parse(process.argv);