@waniwani/cli 0.0.41 → 0.0.42

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
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/cli.ts
4
4
  import { createRequire } from "module";
5
- import { Command as Command24 } from "commander";
5
+ import { Command as Command25 } from "commander";
6
6
 
7
7
  // src/commands/config/index.ts
8
8
  import { Command as Command2 } from "commander";
@@ -350,6 +350,36 @@ var AuthManager = class {
350
350
  var auth = new AuthManager();
351
351
 
352
352
  // src/commands/login.ts
353
+ var LOGO_LINES = [
354
+ "\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557",
355
+ "\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551",
356
+ "\u2588\u2588\u2551 \u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551",
357
+ "\u2588\u2588\u2551\u2588\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551",
358
+ "\u255A\u2588\u2588\u2588\u2554\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2554\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551",
359
+ " \u255A\u2550\u2550\u255D\u255A\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u255D\u255A\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u255D"
360
+ ];
361
+ var LOGO_COLORS = [
362
+ "\x1B[38;5;223m",
363
+ // light peach
364
+ "\x1B[38;5;216m",
365
+ // peach
366
+ "\x1B[38;5;209m",
367
+ // salmon
368
+ "\x1B[38;5;203m",
369
+ // coral
370
+ "\x1B[38;5;167m",
371
+ // warm red
372
+ "\x1B[38;5;131m"
373
+ // deep terracotta
374
+ ];
375
+ var RESET = "\x1B[0m";
376
+ function showLogo() {
377
+ console.log();
378
+ for (let i = 0; i < LOGO_LINES.length; i++) {
379
+ console.log(`${LOGO_COLORS[i]}${LOGO_LINES[i]}${RESET}`);
380
+ }
381
+ console.log();
382
+ }
353
383
  var CALLBACK_PORT = 54321;
354
384
  var CALLBACK_URL = `http://localhost:${CALLBACK_PORT}/callback`;
355
385
  var CLIENT_NAME = "waniwani-cli";
@@ -662,7 +692,7 @@ var loginCommand = new Command3("login").description("Log in to WaniWani").optio
662
692
  }
663
693
  }
664
694
  if (!json) {
665
- console.log(chalk3.bold("\nWaniWani CLI Login\n"));
695
+ showLogo();
666
696
  }
667
697
  const spinner = ora("Registering client...").start();
668
698
  const { client_id: clientId } = await registerClient();
@@ -757,11 +787,13 @@ var logoutCommand = new Command4("logout").description("Log out from WaniWani").
757
787
  });
758
788
 
759
789
  // src/commands/mcp/index.ts
760
- import { Command as Command20 } from "commander";
790
+ import { Command as Command21 } from "commander";
761
791
 
762
- // src/commands/mcp/delete.ts
763
- import { confirm } from "@inquirer/prompts";
764
- import chalk4 from "chalk";
792
+ // src/commands/mcp/clone.ts
793
+ import { execSync } from "child_process";
794
+ import { existsSync as existsSync3 } from "fs";
795
+ import { readFile as readFile2 } from "fs/promises";
796
+ import { join as join3 } from "path";
765
797
  import { Command as Command5 } from "commander";
766
798
  import ora2 from "ora";
767
799
 
@@ -853,13 +885,221 @@ var api = {
853
885
  getBaseUrl: () => config.getApiUrl()
854
886
  };
855
887
 
888
+ // src/commands/mcp/clone.ts
889
+ async function loadParentConfig(cwd) {
890
+ const parentConfigPath = join3(cwd, LOCAL_CONFIG_DIR, CONFIG_FILE_NAME);
891
+ if (!existsSync3(parentConfigPath)) {
892
+ return null;
893
+ }
894
+ try {
895
+ const content = await readFile2(parentConfigPath, "utf-8");
896
+ const config2 = JSON.parse(content);
897
+ const { mcpId: _, sessionId: __, ...rest } = config2;
898
+ return rest;
899
+ } catch {
900
+ return null;
901
+ }
902
+ }
903
+ function checkGitInstalled() {
904
+ try {
905
+ execSync("git --version", { stdio: "ignore" });
906
+ } catch {
907
+ throw new CLIError(
908
+ "git is required but not found. Install it from https://git-scm.com/",
909
+ "GIT_NOT_FOUND"
910
+ );
911
+ }
912
+ }
913
+ var cloneCommand = new Command5("clone").description("Clone an existing MCP project to a local directory").argument("<name>", "Name of the MCP to clone").argument("[directory]", "Directory to clone into (defaults to MCP name)").action(async (name, directory, command) => {
914
+ const globalOptions = command.optsWithGlobals();
915
+ const json = globalOptions.json ?? false;
916
+ try {
917
+ const cwd = process.cwd();
918
+ const dirName = directory ?? name;
919
+ const projectDir = join3(cwd, dirName);
920
+ if (existsSync3(projectDir)) {
921
+ if (json) {
922
+ formatOutput(
923
+ {
924
+ success: false,
925
+ error: `Directory "${dirName}" already exists`
926
+ },
927
+ true
928
+ );
929
+ } else {
930
+ console.error(`Error: Directory "${dirName}" already exists`);
931
+ }
932
+ process.exit(1);
933
+ }
934
+ checkGitInstalled();
935
+ const spinner = ora2("Fetching MCPs...").start();
936
+ const mcps = await api.get(
937
+ "/api/mcp/repositories"
938
+ );
939
+ const mcp = mcps.find((m) => m.name === name);
940
+ if (!mcp) {
941
+ spinner.fail("MCP not found");
942
+ throw new McpError(
943
+ `MCP "${name}" not found. Run 'waniwani mcp list' to see available MCPs.`
944
+ );
945
+ }
946
+ spinner.text = "Cloning repository...";
947
+ const { cloneUrl } = await api.get(
948
+ `/api/mcp/repositories/${mcp.id}/clone-url`
949
+ );
950
+ try {
951
+ execSync(`git clone "${cloneUrl}" "${projectDir}"`, {
952
+ stdio: "ignore"
953
+ });
954
+ } catch {
955
+ spinner.fail("Failed to clone repository");
956
+ throw new CLIError(
957
+ "Failed to clone repository. Ensure git is configured correctly.",
958
+ "CLONE_FAILED"
959
+ );
960
+ }
961
+ const parentConfig = await loadParentConfig(cwd);
962
+ await initConfigAt(projectDir, {
963
+ ...parentConfig,
964
+ mcpId: mcp.id
965
+ });
966
+ spinner.succeed("Repository cloned");
967
+ if (json) {
968
+ formatOutput(
969
+ {
970
+ success: true,
971
+ projectDir,
972
+ mcpId: mcp.id
973
+ },
974
+ true
975
+ );
976
+ } else {
977
+ console.log();
978
+ formatSuccess(`MCP "${name}" cloned!`, false);
979
+ console.log();
980
+ console.log("Next steps:");
981
+ console.log(` cd ${dirName}`);
982
+ console.log(" waniwani mcp preview # Start developing");
983
+ }
984
+ } catch (error) {
985
+ handleError(error, json);
986
+ process.exit(1);
987
+ }
988
+ });
989
+
990
+ // src/commands/mcp/create.ts
991
+ import { execSync as execSync2 } from "child_process";
992
+ import { existsSync as existsSync4 } from "fs";
993
+ import { readFile as readFile3 } from "fs/promises";
994
+ import { join as join4 } from "path";
995
+ import { Command as Command6 } from "commander";
996
+ import ora3 from "ora";
997
+ async function loadParentConfig2(cwd) {
998
+ const parentConfigPath = join4(cwd, LOCAL_CONFIG_DIR, CONFIG_FILE_NAME);
999
+ if (!existsSync4(parentConfigPath)) {
1000
+ return null;
1001
+ }
1002
+ try {
1003
+ const content = await readFile3(parentConfigPath, "utf-8");
1004
+ const config2 = JSON.parse(content);
1005
+ const { mcpId: _, sessionId: __, ...rest } = config2;
1006
+ return rest;
1007
+ } catch {
1008
+ return null;
1009
+ }
1010
+ }
1011
+ function checkGitInstalled2() {
1012
+ try {
1013
+ execSync2("git --version", { stdio: "ignore" });
1014
+ } catch {
1015
+ throw new CLIError(
1016
+ "git is required but not found. Install it from https://git-scm.com/",
1017
+ "GIT_NOT_FOUND"
1018
+ );
1019
+ }
1020
+ }
1021
+ var createCommand = new Command6("create").description("Create a new MCP project").argument("<name>", "Name for the MCP project").action(async (name, _options, command) => {
1022
+ const globalOptions = command.optsWithGlobals();
1023
+ const json = globalOptions.json ?? false;
1024
+ try {
1025
+ const cwd = process.cwd();
1026
+ const projectDir = join4(cwd, name);
1027
+ if (existsSync4(projectDir)) {
1028
+ if (json) {
1029
+ formatOutput(
1030
+ {
1031
+ success: false,
1032
+ error: `Directory "${name}" already exists`
1033
+ },
1034
+ true
1035
+ );
1036
+ } else {
1037
+ console.error(`Error: Directory "${name}" already exists`);
1038
+ }
1039
+ process.exit(1);
1040
+ }
1041
+ checkGitInstalled2();
1042
+ const spinner = ora3("Creating MCP...").start();
1043
+ const result = await api.post("/api/mcp/repositories", {
1044
+ name
1045
+ });
1046
+ spinner.text = "Cloning repository...";
1047
+ const { cloneUrl } = await api.get(
1048
+ `/api/mcp/repositories/${result.id}/clone-url`
1049
+ );
1050
+ try {
1051
+ execSync2(`git clone "${cloneUrl}" "${projectDir}"`, {
1052
+ stdio: "ignore"
1053
+ });
1054
+ } catch {
1055
+ spinner.fail("Failed to clone repository");
1056
+ throw new CLIError(
1057
+ `Failed to clone repository. Ensure git is configured correctly.`,
1058
+ "CLONE_FAILED"
1059
+ );
1060
+ }
1061
+ const parentConfig = await loadParentConfig2(cwd);
1062
+ await initConfigAt(projectDir, {
1063
+ ...parentConfig,
1064
+ mcpId: result.id
1065
+ });
1066
+ spinner.succeed("MCP project created");
1067
+ if (json) {
1068
+ formatOutput(
1069
+ {
1070
+ success: true,
1071
+ projectDir,
1072
+ mcpId: result.id
1073
+ },
1074
+ true
1075
+ );
1076
+ } else {
1077
+ console.log();
1078
+ formatSuccess(`MCP "${name}" created!`, false);
1079
+ console.log();
1080
+ console.log("Next steps:");
1081
+ console.log(` cd ${name}`);
1082
+ console.log(" waniwani mcp preview # Start developing");
1083
+ }
1084
+ } catch (error) {
1085
+ handleError(error, json);
1086
+ process.exit(1);
1087
+ }
1088
+ });
1089
+
1090
+ // src/commands/mcp/delete.ts
1091
+ import { confirm } from "@inquirer/prompts";
1092
+ import chalk4 from "chalk";
1093
+ import { Command as Command7 } from "commander";
1094
+ import ora4 from "ora";
1095
+
856
1096
  // src/lib/utils.ts
857
1097
  async function requireMcpId(mcpId) {
858
1098
  if (mcpId) return mcpId;
859
1099
  const configMcpId = await config.getMcpId();
860
1100
  if (!configMcpId) {
861
1101
  throw new McpError(
862
- "No active MCP. Run 'waniwani mcp init <name>' or 'waniwani mcp use <name>'."
1102
+ "No active MCP. Run 'waniwani mcp create <name>' or 'waniwani mcp use <name>'."
863
1103
  );
864
1104
  }
865
1105
  return configMcpId;
@@ -911,7 +1151,7 @@ function detectBinary(buffer) {
911
1151
  }
912
1152
 
913
1153
  // src/commands/mcp/delete.ts
914
- var deleteCommand = new Command5("delete").description("Delete the MCP (includes all associated resources)").option("--mcp-id <id>", "Specific MCP ID").option("--force", "Skip confirmation prompt").action(async (options, command) => {
1154
+ var deleteCommand = new Command7("delete").description("Delete the MCP (includes all associated resources)").option("--mcp-id <id>", "Specific MCP ID").option("--force", "Skip confirmation prompt").action(async (options, command) => {
915
1155
  const globalOptions = command.optsWithGlobals();
916
1156
  const json = globalOptions.json ?? false;
917
1157
  try {
@@ -936,7 +1176,7 @@ var deleteCommand = new Command5("delete").description("Delete the MCP (includes
936
1176
  return;
937
1177
  }
938
1178
  }
939
- const spinner = ora2("Deleting MCP...").start();
1179
+ const spinner = ora4("Deleting MCP...").start();
940
1180
  await api.delete(`/api/mcp/repositories/${mcpId}`);
941
1181
  spinner.succeed("MCP deleted");
942
1182
  if (await config.getMcpId() === mcpId) {
@@ -955,19 +1195,19 @@ var deleteCommand = new Command5("delete").description("Delete the MCP (includes
955
1195
  });
956
1196
 
957
1197
  // src/commands/mcp/file/index.ts
958
- import { Command as Command9 } from "commander";
1198
+ import { Command as Command11 } from "commander";
959
1199
 
960
1200
  // src/commands/mcp/file/list.ts
961
1201
  import chalk5 from "chalk";
962
- import { Command as Command6 } from "commander";
963
- import ora3 from "ora";
964
- var listCommand = new Command6("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) => {
1202
+ import { Command as Command8 } from "commander";
1203
+ import ora5 from "ora";
1204
+ var listCommand = new Command8("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) => {
965
1205
  const globalOptions = command.optsWithGlobals();
966
1206
  const json = globalOptions.json ?? false;
967
1207
  try {
968
1208
  await requireMcpId(options.mcpId);
969
1209
  const sessionId = await requireSessionId();
970
- const spinner = ora3(`Listing ${path}...`).start();
1210
+ const spinner = ora5(`Listing ${path}...`).start();
971
1211
  const result = await api.get(
972
1212
  `/api/mcp/sessions/${sessionId}/files/list?path=${encodeURIComponent(path)}`
973
1213
  );
@@ -1004,16 +1244,16 @@ function formatSize(bytes) {
1004
1244
 
1005
1245
  // src/commands/mcp/file/read.ts
1006
1246
  import { writeFile as writeFile2 } from "fs/promises";
1007
- import { Command as Command7 } from "commander";
1008
- import ora4 from "ora";
1009
- var readCommand = new Command7("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) => {
1247
+ import { Command as Command9 } from "commander";
1248
+ import ora6 from "ora";
1249
+ var readCommand = new Command9("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) => {
1010
1250
  const globalOptions = command.optsWithGlobals();
1011
1251
  const json = globalOptions.json ?? false;
1012
1252
  try {
1013
1253
  await requireMcpId(options.mcpId);
1014
1254
  const sessionId = await requireSessionId();
1015
1255
  const encoding = options.base64 ? "base64" : "utf8";
1016
- const spinner = ora4(`Reading ${path}...`).start();
1256
+ const spinner = ora6(`Reading ${path}...`).start();
1017
1257
  const result = await api.get(
1018
1258
  `/api/mcp/sessions/${sessionId}/files?path=${encodeURIComponent(path)}&encoding=${encoding}`
1019
1259
  );
@@ -1044,10 +1284,10 @@ var readCommand = new Command7("read").description("Read a file from the MCP san
1044
1284
  });
1045
1285
 
1046
1286
  // src/commands/mcp/file/write.ts
1047
- import { readFile as readFile2 } from "fs/promises";
1048
- import { Command as Command8 } from "commander";
1049
- import ora5 from "ora";
1050
- var writeCommand = new Command8("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) => {
1287
+ import { readFile as readFile4 } from "fs/promises";
1288
+ import { Command as Command10 } from "commander";
1289
+ import ora7 from "ora";
1290
+ var writeCommand = new Command10("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) => {
1051
1291
  const globalOptions = command.optsWithGlobals();
1052
1292
  const json = globalOptions.json ?? false;
1053
1293
  try {
@@ -1061,7 +1301,7 @@ var writeCommand = new Command8("write").description("Write a file to the MCP sa
1061
1301
  encoding = "base64";
1062
1302
  }
1063
1303
  } else if (options.file) {
1064
- const fileBuffer = await readFile2(options.file);
1304
+ const fileBuffer = await readFile4(options.file);
1065
1305
  if (options.base64) {
1066
1306
  content = fileBuffer.toString("base64");
1067
1307
  encoding = "base64";
@@ -1074,7 +1314,7 @@ var writeCommand = new Command8("write").description("Write a file to the MCP sa
1074
1314
  "MISSING_CONTENT"
1075
1315
  );
1076
1316
  }
1077
- const spinner = ora5(`Writing ${path}...`).start();
1317
+ const spinner = ora7(`Writing ${path}...`).start();
1078
1318
  const result = await api.post(
1079
1319
  `/api/mcp/sessions/${sessionId}/files`,
1080
1320
  {
@@ -1094,275 +1334,73 @@ var writeCommand = new Command8("write").description("Write a file to the MCP sa
1094
1334
  });
1095
1335
 
1096
1336
  // src/commands/mcp/file/index.ts
1097
- var fileCommand = new Command9("file").description("File operations in MCP sandbox").addCommand(readCommand).addCommand(writeCommand).addCommand(listCommand);
1098
-
1099
- // src/commands/mcp/init.ts
1100
- import { existsSync as existsSync4, mkdirSync } from "fs";
1101
- import { readFile as readFile4 } from "fs/promises";
1102
- import { join as join4 } from "path";
1103
- import { Command as Command10 } from "commander";
1104
- import ora6 from "ora";
1337
+ var fileCommand = new Command11("file").description("File operations in MCP sandbox").addCommand(readCommand).addCommand(writeCommand).addCommand(listCommand);
1105
1338
 
1106
- // src/lib/sync.ts
1107
- import { existsSync as existsSync3 } from "fs";
1108
- import { mkdir as mkdir2, readdir, readFile as readFile3, stat, writeFile as writeFile3 } from "fs/promises";
1109
- import { dirname, join as join3, relative } from "path";
1110
- import ignore from "ignore";
1111
- var PROJECT_DIR = ".waniwani";
1112
- async function findProjectRoot(startDir) {
1113
- let current = startDir;
1114
- const root = dirname(current);
1115
- while (current !== root) {
1116
- if (existsSync3(join3(current, PROJECT_DIR))) {
1117
- return current;
1339
+ // src/commands/mcp/list.ts
1340
+ import chalk6 from "chalk";
1341
+ import { Command as Command12 } from "commander";
1342
+ import ora8 from "ora";
1343
+ var listCommand2 = new Command12("list").description("List all MCPs in your organization").action(async (_, command) => {
1344
+ const globalOptions = command.optsWithGlobals();
1345
+ const json = globalOptions.json ?? false;
1346
+ try {
1347
+ const spinner = ora8("Fetching MCPs...").start();
1348
+ const mcps = await api.get(
1349
+ "/api/mcp/repositories"
1350
+ );
1351
+ spinner.stop();
1352
+ const activeMcpId = await config.getMcpId();
1353
+ if (json) {
1354
+ formatOutput(
1355
+ {
1356
+ mcps: mcps.map((m) => ({
1357
+ ...m,
1358
+ isActive: m.id === activeMcpId
1359
+ })),
1360
+ activeMcpId
1361
+ },
1362
+ true
1363
+ );
1364
+ } else {
1365
+ if (mcps.length === 0) {
1366
+ console.log("No MCPs found.");
1367
+ console.log("\nCreate a new MCP: waniwani mcp create <name>");
1368
+ return;
1369
+ }
1370
+ console.log(chalk6.bold("\nMCPs:\n"));
1371
+ const rows = mcps.map((m) => {
1372
+ const isActive = m.id === activeMcpId;
1373
+ const deployStatus = m.deployedAt ? chalk6.green("Deployed") : chalk6.yellow("Pending");
1374
+ const sandboxStatus = m.activeSandbox ? chalk6.green("Active") : chalk6.gray("None");
1375
+ const lastDeploy = m.deployedAt ? new Date(m.deployedAt).toLocaleDateString() : chalk6.gray("Never");
1376
+ return [
1377
+ isActive ? chalk6.cyan(`* ${m.name}`) : ` ${m.name}`,
1378
+ deployStatus,
1379
+ sandboxStatus,
1380
+ lastDeploy
1381
+ ];
1382
+ });
1383
+ formatTable(["Name", "Status", "Sandbox", "Last Deploy"], rows, false);
1384
+ console.log();
1385
+ if (activeMcpId) {
1386
+ const activeMcp = mcps.find((m) => m.id === activeMcpId);
1387
+ if (activeMcp) {
1388
+ console.log(`Active MCP: ${chalk6.cyan(activeMcp.name)}`);
1389
+ }
1390
+ }
1391
+ console.log("\nSelect an MCP: waniwani mcp use <name>");
1118
1392
  }
1119
- const parent = dirname(current);
1120
- if (parent === current) break;
1121
- current = parent;
1122
- }
1123
- if (existsSync3(join3(current, PROJECT_DIR))) {
1124
- return current;
1125
- }
1126
- return null;
1127
- }
1128
- var DEFAULT_IGNORE_PATTERNS = [
1129
- ".waniwani",
1130
- ".git",
1131
- "node_modules",
1132
- ".env",
1133
- ".env.*",
1134
- ".DS_Store",
1135
- "*.log",
1136
- ".cache",
1137
- "dist",
1138
- "coverage",
1139
- ".turbo",
1140
- ".next",
1141
- ".nuxt",
1142
- ".vercel"
1143
- ];
1144
- async function loadIgnorePatterns(projectRoot) {
1145
- const ig = ignore();
1146
- ig.add(DEFAULT_IGNORE_PATTERNS);
1147
- const gitignorePath = join3(projectRoot, ".gitignore");
1148
- if (existsSync3(gitignorePath)) {
1149
- try {
1150
- const content = await readFile3(gitignorePath, "utf-8");
1151
- ig.add(content);
1152
- } catch {
1153
- }
1154
- }
1155
- return ig;
1156
- }
1157
- async function collectFiles(projectRoot) {
1158
- const ig = await loadIgnorePatterns(projectRoot);
1159
- const files = [];
1160
- async function walk(dir) {
1161
- const entries = await readdir(dir, { withFileTypes: true });
1162
- for (const entry of entries) {
1163
- const fullPath = join3(dir, entry.name);
1164
- const relativePath = relative(projectRoot, fullPath);
1165
- if (ig.ignores(relativePath)) {
1166
- continue;
1167
- }
1168
- if (entry.isDirectory()) {
1169
- await walk(fullPath);
1170
- } else if (entry.isFile()) {
1171
- try {
1172
- const content = await readFile3(fullPath);
1173
- const isBinary = isBinaryPath(fullPath) || detectBinary(content);
1174
- files.push({
1175
- path: relativePath,
1176
- content: isBinary ? content.toString("base64") : content.toString("utf8"),
1177
- encoding: isBinary ? "base64" : "utf8"
1178
- });
1179
- } catch {
1180
- }
1181
- }
1182
- }
1183
- }
1184
- await walk(projectRoot);
1185
- return files;
1186
- }
1187
- async function pullFilesFromGithub(mcpId, targetDir) {
1188
- const result = await api.get(
1189
- `/api/mcp/repositories/${mcpId}/files`
1190
- );
1191
- const writtenFiles = [];
1192
- for (const file of result.files) {
1193
- const localPath = join3(targetDir, file.path);
1194
- const dir = dirname(localPath);
1195
- await mkdir2(dir, { recursive: true });
1196
- if (file.encoding === "base64") {
1197
- await writeFile3(localPath, Buffer.from(file.content, "base64"));
1198
- } else {
1199
- await writeFile3(localPath, file.content, "utf8");
1200
- }
1201
- writtenFiles.push(file.path);
1202
- }
1203
- return { count: writtenFiles.length, files: writtenFiles };
1204
- }
1205
- async function collectSingleFile(projectRoot, filePath) {
1206
- const fullPath = join3(projectRoot, filePath);
1207
- const relativePath = relative(projectRoot, fullPath);
1208
- if (!existsSync3(fullPath)) {
1209
- return null;
1210
- }
1211
- try {
1212
- const fileStat = await stat(fullPath);
1213
- if (!fileStat.isFile()) {
1214
- return null;
1215
- }
1216
- const content = await readFile3(fullPath);
1217
- const isBinary = isBinaryPath(fullPath) || detectBinary(content);
1218
- return {
1219
- path: relativePath,
1220
- content: isBinary ? content.toString("base64") : content.toString("utf8"),
1221
- encoding: isBinary ? "base64" : "utf8"
1222
- };
1223
- } catch {
1224
- return null;
1225
- }
1226
- }
1227
-
1228
- // src/commands/mcp/init.ts
1229
- async function loadParentConfig(cwd) {
1230
- const parentConfigPath = join4(cwd, LOCAL_CONFIG_DIR, CONFIG_FILE_NAME);
1231
- if (!existsSync4(parentConfigPath)) {
1232
- return null;
1233
- }
1234
- try {
1235
- const content = await readFile4(parentConfigPath, "utf-8");
1236
- const config2 = JSON.parse(content);
1237
- const { mcpId: _, sessionId: __, ...rest } = config2;
1238
- return rest;
1239
- } catch {
1240
- return null;
1241
- }
1242
- }
1243
- var initCommand = new Command10("init").description("Create a new MCP project").argument("<name>", "Name for the MCP project").action(async (name, _options, command) => {
1244
- const globalOptions = command.optsWithGlobals();
1245
- const json = globalOptions.json ?? false;
1246
- try {
1247
- const cwd = process.cwd();
1248
- const projectDir = join4(cwd, name);
1249
- if (existsSync4(projectDir)) {
1250
- if (json) {
1251
- formatOutput(
1252
- {
1253
- success: false,
1254
- error: `Directory "${name}" already exists`
1255
- },
1256
- true
1257
- );
1258
- } else {
1259
- console.error(`Error: Directory "${name}" already exists`);
1260
- }
1261
- process.exit(1);
1262
- }
1263
- const spinner = ora6("Creating MCP...").start();
1264
- const result = await api.post("/api/mcp/repositories", {
1265
- name
1266
- });
1267
- mkdirSync(projectDir, { recursive: true });
1268
- const parentConfig = await loadParentConfig(cwd);
1269
- await initConfigAt(projectDir, {
1270
- ...parentConfig,
1271
- mcpId: result.id
1272
- });
1273
- spinner.succeed("MCP project created");
1274
- spinner.start("Pulling template files...");
1275
- const syncResult = await pullFilesFromGithub(result.id, projectDir);
1276
- spinner.succeed(`Pulled ${syncResult.count} files`);
1277
- if (json) {
1278
- formatOutput(
1279
- {
1280
- success: true,
1281
- projectDir,
1282
- mcpId: result.id,
1283
- files: syncResult.files
1284
- },
1285
- true
1286
- );
1287
- } else {
1288
- console.log();
1289
- formatSuccess(`MCP "${name}" created!`, false);
1290
- console.log();
1291
- console.log("Next steps:");
1292
- console.log(` cd ${name}`);
1293
- console.log(" waniwani mcp preview # Start developing");
1294
- }
1295
- } catch (error) {
1296
- handleError(error, json);
1297
- process.exit(1);
1298
- }
1299
- });
1300
-
1301
- // src/commands/mcp/list.ts
1302
- import chalk6 from "chalk";
1303
- import { Command as Command11 } from "commander";
1304
- import ora7 from "ora";
1305
- var listCommand2 = new Command11("list").description("List all MCPs in your organization").action(async (_, command) => {
1306
- const globalOptions = command.optsWithGlobals();
1307
- const json = globalOptions.json ?? false;
1308
- try {
1309
- const spinner = ora7("Fetching MCPs...").start();
1310
- const mcps = await api.get(
1311
- "/api/mcp/repositories"
1312
- );
1313
- spinner.stop();
1314
- const activeMcpId = await config.getMcpId();
1315
- if (json) {
1316
- formatOutput(
1317
- {
1318
- mcps: mcps.map((m) => ({
1319
- ...m,
1320
- isActive: m.id === activeMcpId
1321
- })),
1322
- activeMcpId
1323
- },
1324
- true
1325
- );
1326
- } else {
1327
- if (mcps.length === 0) {
1328
- console.log("No MCPs found.");
1329
- console.log("\nCreate a new MCP: waniwani mcp init <name>");
1330
- return;
1331
- }
1332
- console.log(chalk6.bold("\nMCPs:\n"));
1333
- const rows = mcps.map((m) => {
1334
- const isActive = m.id === activeMcpId;
1335
- const deployStatus = m.deployedAt ? chalk6.green("Deployed") : chalk6.yellow("Pending");
1336
- const sandboxStatus = m.activeSandbox ? chalk6.green("Active") : chalk6.gray("None");
1337
- const lastDeploy = m.deployedAt ? new Date(m.deployedAt).toLocaleDateString() : chalk6.gray("Never");
1338
- return [
1339
- isActive ? chalk6.cyan(`* ${m.name}`) : ` ${m.name}`,
1340
- deployStatus,
1341
- sandboxStatus,
1342
- lastDeploy
1343
- ];
1344
- });
1345
- formatTable(["Name", "Status", "Sandbox", "Last Deploy"], rows, false);
1346
- console.log();
1347
- if (activeMcpId) {
1348
- const activeMcp = mcps.find((m) => m.id === activeMcpId);
1349
- if (activeMcp) {
1350
- console.log(`Active MCP: ${chalk6.cyan(activeMcp.name)}`);
1351
- }
1352
- }
1353
- console.log("\nSelect an MCP: waniwani mcp use <name>");
1354
- }
1355
- } catch (error) {
1356
- handleError(error, json);
1357
- process.exit(1);
1393
+ } catch (error) {
1394
+ handleError(error, json);
1395
+ process.exit(1);
1358
1396
  }
1359
1397
  });
1360
1398
 
1361
1399
  // src/commands/mcp/logs.ts
1362
1400
  import chalk7 from "chalk";
1363
- import { Command as Command12 } from "commander";
1364
- import ora8 from "ora";
1365
- 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) => {
1401
+ import { Command as Command13 } from "commander";
1402
+ import ora9 from "ora";
1403
+ var logsCommand = new Command13("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) => {
1366
1404
  const globalOptions = command.optsWithGlobals();
1367
1405
  const json = globalOptions.json ?? false;
1368
1406
  let reader;
@@ -1386,7 +1424,7 @@ var logsCommand = new Command12("logs").description("Stream logs from the MCP se
1386
1424
  }
1387
1425
  let cmdId = cmdIdArg;
1388
1426
  if (!cmdId) {
1389
- const spinner = ora8("Getting server status...").start();
1427
+ const spinner = ora9("Getting server status...").start();
1390
1428
  const status = await api.post(
1391
1429
  `/api/mcp/sessions/${sessionId}/server`,
1392
1430
  { action: "status" }
@@ -1503,16 +1541,140 @@ Error: ${event.error}`));
1503
1541
 
1504
1542
  // src/commands/mcp/preview.ts
1505
1543
  import { watch } from "chokidar";
1506
- import { Command as Command13 } from "commander";
1507
- import ora9 from "ora";
1508
- var previewCommand = new Command13("preview").description("Start live development with sandbox and file watching").option("--mcp-id <id>", "Specific MCP ID").option("--no-watch", "Skip file watching").option("--no-logs", "Don't stream logs to terminal").action(async (options, command) => {
1544
+ import { Command as Command14 } from "commander";
1545
+ import ora10 from "ora";
1546
+
1547
+ // src/lib/sync.ts
1548
+ import { existsSync as existsSync5 } from "fs";
1549
+ import { mkdir as mkdir2, readdir, readFile as readFile5, stat, writeFile as writeFile3 } from "fs/promises";
1550
+ import { dirname, join as join5, relative } from "path";
1551
+ import ignore from "ignore";
1552
+ var PROJECT_DIR = ".waniwani";
1553
+ async function findProjectRoot(startDir) {
1554
+ let current = startDir;
1555
+ const root = dirname(current);
1556
+ while (current !== root) {
1557
+ if (existsSync5(join5(current, PROJECT_DIR))) {
1558
+ return current;
1559
+ }
1560
+ const parent = dirname(current);
1561
+ if (parent === current) break;
1562
+ current = parent;
1563
+ }
1564
+ if (existsSync5(join5(current, PROJECT_DIR))) {
1565
+ return current;
1566
+ }
1567
+ return null;
1568
+ }
1569
+ var DEFAULT_IGNORE_PATTERNS = [
1570
+ ".waniwani",
1571
+ ".git",
1572
+ "node_modules",
1573
+ ".env",
1574
+ ".env.*",
1575
+ ".DS_Store",
1576
+ "*.log",
1577
+ ".cache",
1578
+ "dist",
1579
+ "coverage",
1580
+ ".turbo",
1581
+ ".next",
1582
+ ".nuxt",
1583
+ ".vercel"
1584
+ ];
1585
+ async function loadIgnorePatterns(projectRoot) {
1586
+ const ig = ignore();
1587
+ ig.add(DEFAULT_IGNORE_PATTERNS);
1588
+ const gitignorePath = join5(projectRoot, ".gitignore");
1589
+ if (existsSync5(gitignorePath)) {
1590
+ try {
1591
+ const content = await readFile5(gitignorePath, "utf-8");
1592
+ ig.add(content);
1593
+ } catch {
1594
+ }
1595
+ }
1596
+ return ig;
1597
+ }
1598
+ async function collectFiles(projectRoot) {
1599
+ const ig = await loadIgnorePatterns(projectRoot);
1600
+ const files = [];
1601
+ async function walk(dir) {
1602
+ const entries = await readdir(dir, { withFileTypes: true });
1603
+ for (const entry of entries) {
1604
+ const fullPath = join5(dir, entry.name);
1605
+ const relativePath = relative(projectRoot, fullPath);
1606
+ if (ig.ignores(relativePath)) {
1607
+ continue;
1608
+ }
1609
+ if (entry.isDirectory()) {
1610
+ await walk(fullPath);
1611
+ } else if (entry.isFile()) {
1612
+ try {
1613
+ const content = await readFile5(fullPath);
1614
+ const isBinary = isBinaryPath(fullPath) || detectBinary(content);
1615
+ files.push({
1616
+ path: relativePath,
1617
+ content: isBinary ? content.toString("base64") : content.toString("utf8"),
1618
+ encoding: isBinary ? "base64" : "utf8"
1619
+ });
1620
+ } catch {
1621
+ }
1622
+ }
1623
+ }
1624
+ }
1625
+ await walk(projectRoot);
1626
+ return files;
1627
+ }
1628
+ async function pullFilesFromGithub(mcpId, targetDir) {
1629
+ const result = await api.get(
1630
+ `/api/mcp/repositories/${mcpId}/files`
1631
+ );
1632
+ const writtenFiles = [];
1633
+ for (const file of result.files) {
1634
+ const localPath = join5(targetDir, file.path);
1635
+ const dir = dirname(localPath);
1636
+ await mkdir2(dir, { recursive: true });
1637
+ if (file.encoding === "base64") {
1638
+ await writeFile3(localPath, Buffer.from(file.content, "base64"));
1639
+ } else {
1640
+ await writeFile3(localPath, file.content, "utf8");
1641
+ }
1642
+ writtenFiles.push(file.path);
1643
+ }
1644
+ return { count: writtenFiles.length, files: writtenFiles };
1645
+ }
1646
+ async function collectSingleFile(projectRoot, filePath) {
1647
+ const fullPath = join5(projectRoot, filePath);
1648
+ const relativePath = relative(projectRoot, fullPath);
1649
+ if (!existsSync5(fullPath)) {
1650
+ return null;
1651
+ }
1652
+ try {
1653
+ const fileStat = await stat(fullPath);
1654
+ if (!fileStat.isFile()) {
1655
+ return null;
1656
+ }
1657
+ const content = await readFile5(fullPath);
1658
+ const isBinary = isBinaryPath(fullPath) || detectBinary(content);
1659
+ return {
1660
+ path: relativePath,
1661
+ content: isBinary ? content.toString("base64") : content.toString("utf8"),
1662
+ encoding: isBinary ? "base64" : "utf8"
1663
+ };
1664
+ } catch {
1665
+ return null;
1666
+ }
1667
+ }
1668
+
1669
+ // src/commands/mcp/preview.ts
1670
+ var previewCommand = new Command14("preview").description("Start live development with sandbox and file watching").option("--mcp-id <id>", "Specific MCP ID").option("--no-watch", "Skip file watching").option("--no-logs", "Don't stream logs to terminal").action(async (options, command) => {
1509
1671
  const globalOptions = command.optsWithGlobals();
1510
1672
  const json = globalOptions.json ?? false;
1511
1673
  try {
1512
1674
  const projectRoot = await findProjectRoot(process.cwd());
1513
1675
  if (!projectRoot) {
1514
1676
  throw new CLIError(
1515
- "Not in a WaniWani project. Run 'waniwani mcp init <name>' first.",
1677
+ "Not in a WaniWani project. Run 'waniwani mcp create <name>' first.",
1516
1678
  "NOT_IN_PROJECT"
1517
1679
  );
1518
1680
  }
@@ -1522,11 +1684,11 @@ var previewCommand = new Command13("preview").description("Start live developmen
1522
1684
  }
1523
1685
  if (!mcpId) {
1524
1686
  throw new CLIError(
1525
- "No MCP found. Run 'waniwani mcp init <name>' or use --mcp-id.",
1687
+ "No MCP found. Run 'waniwani mcp create <name>' or use --mcp-id.",
1526
1688
  "NO_MCP"
1527
1689
  );
1528
1690
  }
1529
- const spinner = ora9("Starting development environment...").start();
1691
+ const spinner = ora10("Starting development environment...").start();
1530
1692
  spinner.text = "Starting session...";
1531
1693
  let sessionId;
1532
1694
  let previewUrl;
@@ -1622,9 +1784,9 @@ var previewCommand = new Command13("preview").description("Start live developmen
1622
1784
 
1623
1785
  // src/commands/mcp/publish.ts
1624
1786
  import { input } from "@inquirer/prompts";
1625
- import { Command as Command14 } from "commander";
1626
- import ora10 from "ora";
1627
- var publishCommand = new Command14("publish").description("Push local files to GitHub and trigger deployment").option("-m, --message <msg>", "Commit message").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
1787
+ import { Command as Command15 } from "commander";
1788
+ import ora11 from "ora";
1789
+ var publishCommand = new Command15("publish").description("Push local files to GitHub and trigger deployment").option("-m, --message <msg>", "Commit message").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
1628
1790
  const globalOptions = command.optsWithGlobals();
1629
1791
  const json = globalOptions.json ?? false;
1630
1792
  try {
@@ -1632,7 +1794,7 @@ var publishCommand = new Command14("publish").description("Push local files to G
1632
1794
  const projectRoot = await findProjectRoot(process.cwd());
1633
1795
  if (!projectRoot) {
1634
1796
  throw new CLIError(
1635
- "Not in a WaniWani project. Run 'waniwani mcp init <name>' first.",
1797
+ "Not in a WaniWani project. Run 'waniwani mcp create <name>' first.",
1636
1798
  "NOT_IN_PROJECT"
1637
1799
  );
1638
1800
  }
@@ -1643,7 +1805,7 @@ var publishCommand = new Command14("publish").description("Push local files to G
1643
1805
  validate: (value) => value.trim() ? true : "Commit message is required"
1644
1806
  });
1645
1807
  }
1646
- const spinner = ora10("Collecting files...").start();
1808
+ const spinner = ora11("Collecting files...").start();
1647
1809
  const files = await collectFiles(projectRoot);
1648
1810
  if (files.length === 0) {
1649
1811
  spinner.fail("No files to deploy");
@@ -1671,9 +1833,9 @@ var publishCommand = new Command14("publish").description("Push local files to G
1671
1833
 
1672
1834
  // src/commands/mcp/run-command.ts
1673
1835
  import chalk8 from "chalk";
1674
- import { Command as Command15 } from "commander";
1675
- import ora11 from "ora";
1676
- 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(
1836
+ import { Command as Command16 } from "commander";
1837
+ import ora12 from "ora";
1838
+ var runCommandCommand = new Command16("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(
1677
1839
  "--timeout <ms>",
1678
1840
  "Command timeout in milliseconds (default: 30000, max: 300000)"
1679
1841
  ).action(async (cmd, args, options, command) => {
@@ -1683,7 +1845,7 @@ var runCommandCommand = new Command15("run-command").description("Run a command
1683
1845
  await requireMcpId(options.mcpId);
1684
1846
  const sessionId = await requireSessionId();
1685
1847
  const timeout = options.timeout ? Number.parseInt(options.timeout, 10) : void 0;
1686
- const spinner = ora11(`Running: ${cmd} ${args.join(" ")}`.trim()).start();
1848
+ const spinner = ora12(`Running: ${cmd} ${args.join(" ")}`.trim()).start();
1687
1849
  const result = await api.post(
1688
1850
  `/api/mcp/sessions/${sessionId}/commands`,
1689
1851
  {
@@ -1730,14 +1892,14 @@ var runCommandCommand = new Command15("run-command").description("Run a command
1730
1892
 
1731
1893
  // src/commands/mcp/status.ts
1732
1894
  import chalk9 from "chalk";
1733
- import { Command as Command16 } from "commander";
1734
- import ora12 from "ora";
1735
- var statusCommand = new Command16("status").description("Show current MCP status").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
1895
+ import { Command as Command17 } from "commander";
1896
+ import ora13 from "ora";
1897
+ var statusCommand = new Command17("status").description("Show current MCP status").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
1736
1898
  const globalOptions = command.optsWithGlobals();
1737
1899
  const json = globalOptions.json ?? false;
1738
1900
  try {
1739
1901
  const mcpId = await requireMcpId(options.mcpId);
1740
- const spinner = ora12("Fetching MCP status...").start();
1902
+ const spinner = ora13("Fetching MCP status...").start();
1741
1903
  const result = await api.get(
1742
1904
  `/api/mcp/repositories/${mcpId}`
1743
1905
  );
@@ -1806,15 +1968,15 @@ var statusCommand = new Command16("status").description("Show current MCP status
1806
1968
  });
1807
1969
 
1808
1970
  // src/commands/mcp/stop.ts
1809
- import { Command as Command17 } from "commander";
1810
- import ora13 from "ora";
1811
- var stopCommand = new Command17("stop").description("Stop the development environment (sandbox + server)").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
1971
+ import { Command as Command18 } from "commander";
1972
+ import ora14 from "ora";
1973
+ var stopCommand = new Command18("stop").description("Stop the development environment (sandbox + server)").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
1812
1974
  const globalOptions = command.optsWithGlobals();
1813
1975
  const json = globalOptions.json ?? false;
1814
1976
  try {
1815
1977
  await requireMcpId(options.mcpId);
1816
1978
  const sessionId = await requireSessionId();
1817
- const spinner = ora13("Stopping development environment...").start();
1979
+ const spinner = ora14("Stopping development environment...").start();
1818
1980
  try {
1819
1981
  await api.post(`/api/mcp/sessions/${sessionId}/server`, {
1820
1982
  action: "stop"
@@ -1838,9 +2000,9 @@ var stopCommand = new Command17("stop").description("Stop the development enviro
1838
2000
  });
1839
2001
 
1840
2002
  // src/commands/mcp/sync.ts
1841
- import { Command as Command18 } from "commander";
1842
- import ora14 from "ora";
1843
- var syncCommand = new Command18("sync").description("Pull template files to local project").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
2003
+ import { Command as Command19 } from "commander";
2004
+ import ora15 from "ora";
2005
+ var syncCommand = new Command19("sync").description("Pull template files to local project").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
1844
2006
  const globalOptions = command.optsWithGlobals();
1845
2007
  const json = globalOptions.json ?? false;
1846
2008
  try {
@@ -1848,11 +2010,11 @@ var syncCommand = new Command18("sync").description("Pull template files to loca
1848
2010
  const projectRoot = await findProjectRoot(process.cwd());
1849
2011
  if (!projectRoot) {
1850
2012
  throw new CLIError(
1851
- "Not in a WaniWani project. Run 'waniwani mcp init <name>' first.",
2013
+ "Not in a WaniWani project. Run 'waniwani mcp create <name>' first.",
1852
2014
  "NOT_IN_PROJECT"
1853
2015
  );
1854
2016
  }
1855
- const spinner = ora14("Pulling files...").start();
2017
+ const spinner = ora15("Pulling files...").start();
1856
2018
  const result = await pullFilesFromGithub(mcpId, projectRoot);
1857
2019
  spinner.succeed(`Pulled ${result.count} files`);
1858
2020
  if (json) {
@@ -1874,13 +2036,13 @@ var syncCommand = new Command18("sync").description("Pull template files to loca
1874
2036
  });
1875
2037
 
1876
2038
  // src/commands/mcp/use.ts
1877
- import { Command as Command19 } from "commander";
1878
- import ora15 from "ora";
1879
- var useCommand = new Command19("use").description("Select an MCP to use for subsequent commands").argument("<name>", "Name of the MCP to use").action(async (name, _options, command) => {
2039
+ import { Command as Command20 } from "commander";
2040
+ import ora16 from "ora";
2041
+ var useCommand = new Command20("use").description("Select an MCP to use for subsequent commands").argument("<name>", "Name of the MCP to use").action(async (name, _options, command) => {
1880
2042
  const globalOptions = command.optsWithGlobals();
1881
2043
  const json = globalOptions.json ?? false;
1882
2044
  try {
1883
- const spinner = ora15("Fetching MCPs...").start();
2045
+ const spinner = ora16("Fetching MCPs...").start();
1884
2046
  const mcps = await api.get(
1885
2047
  "/api/mcp/repositories"
1886
2048
  );
@@ -1911,20 +2073,20 @@ var useCommand = new Command19("use").description("Select an MCP to use for subs
1911
2073
  });
1912
2074
 
1913
2075
  // src/commands/mcp/index.ts
1914
- var mcpCommand = new Command20("mcp").description("MCP management commands").addCommand(initCommand).addCommand(listCommand2).addCommand(useCommand).addCommand(statusCommand).addCommand(previewCommand).addCommand(stopCommand).addCommand(logsCommand).addCommand(syncCommand).addCommand(publishCommand).addCommand(deleteCommand).addCommand(fileCommand).addCommand(runCommandCommand);
2076
+ var mcpCommand = new Command21("mcp").description("MCP management commands").addCommand(createCommand).addCommand(cloneCommand).addCommand(listCommand2).addCommand(useCommand).addCommand(statusCommand).addCommand(previewCommand).addCommand(stopCommand).addCommand(logsCommand).addCommand(syncCommand).addCommand(publishCommand).addCommand(deleteCommand).addCommand(fileCommand).addCommand(runCommandCommand);
1915
2077
 
1916
2078
  // src/commands/org/index.ts
1917
- import { Command as Command23 } from "commander";
2079
+ import { Command as Command24 } from "commander";
1918
2080
 
1919
2081
  // src/commands/org/list.ts
1920
2082
  import chalk10 from "chalk";
1921
- import { Command as Command21 } from "commander";
1922
- import ora16 from "ora";
1923
- var listCommand3 = new Command21("list").description("List your organizations").action(async (_, command) => {
2083
+ import { Command as Command22 } from "commander";
2084
+ import ora17 from "ora";
2085
+ var listCommand3 = new Command22("list").description("List your organizations").action(async (_, command) => {
1924
2086
  const globalOptions = command.optsWithGlobals();
1925
2087
  const json = globalOptions.json ?? false;
1926
2088
  try {
1927
- const spinner = ora16("Fetching organizations...").start();
2089
+ const spinner = ora17("Fetching organizations...").start();
1928
2090
  const result = await api.get("/api/oauth/orgs");
1929
2091
  spinner.stop();
1930
2092
  const { orgs, activeOrgId } = result;
@@ -1970,13 +2132,13 @@ var listCommand3 = new Command21("list").description("List your organizations").
1970
2132
  });
1971
2133
 
1972
2134
  // src/commands/org/switch.ts
1973
- import { Command as Command22 } from "commander";
1974
- import ora17 from "ora";
1975
- 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) => {
2135
+ import { Command as Command23 } from "commander";
2136
+ import ora18 from "ora";
2137
+ var switchCommand = new Command23("switch").description("Switch to a different organization").argument("<name>", "Name or slug of the organization to switch to").action(async (name, _, command) => {
1976
2138
  const globalOptions = command.optsWithGlobals();
1977
2139
  const json = globalOptions.json ?? false;
1978
2140
  try {
1979
- const spinner = ora17("Fetching organizations...").start();
2141
+ const spinner = ora18("Fetching organizations...").start();
1980
2142
  const { orgs } = await api.get("/api/oauth/orgs");
1981
2143
  const org = orgs.find((o) => o.name === name || o.slug === name);
1982
2144
  if (!org) {
@@ -2009,12 +2171,12 @@ var switchCommand = new Command22("switch").description("Switch to a different o
2009
2171
  });
2010
2172
 
2011
2173
  // src/commands/org/index.ts
2012
- var orgCommand = new Command23("org").description("Organization management commands").addCommand(listCommand3).addCommand(switchCommand);
2174
+ var orgCommand = new Command24("org").description("Organization management commands").addCommand(listCommand3).addCommand(switchCommand);
2013
2175
 
2014
2176
  // src/cli.ts
2015
2177
  var require2 = createRequire(import.meta.url);
2016
2178
  var { version } = require2("../package.json");
2017
- var program = new Command24().name("waniwani").description("WaniWani CLI for MCP development workflow").version(version).option("--json", "Output results as JSON").option("--verbose", "Enable verbose logging");
2179
+ 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");
2018
2180
  program.addCommand(loginCommand);
2019
2181
  program.addCommand(logoutCommand);
2020
2182
  program.addCommand(mcpCommand);