@waniwani/cli 0.0.41 → 0.0.43

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;
@@ -1621,10 +1783,11 @@ var previewCommand = new Command13("preview").description("Start live developmen
1621
1783
  });
1622
1784
 
1623
1785
  // src/commands/mcp/publish.ts
1786
+ import { execSync as execSync3 } from "child_process";
1624
1787
  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) => {
1788
+ import { Command as Command15 } from "commander";
1789
+ import ora11 from "ora";
1790
+ 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
1791
  const globalOptions = command.optsWithGlobals();
1629
1792
  const json = globalOptions.json ?? false;
1630
1793
  try {
@@ -1632,10 +1795,33 @@ var publishCommand = new Command14("publish").description("Push local files to G
1632
1795
  const projectRoot = await findProjectRoot(process.cwd());
1633
1796
  if (!projectRoot) {
1634
1797
  throw new CLIError(
1635
- "Not in a WaniWani project. Run 'waniwani mcp init <name>' first.",
1798
+ "Not in a WaniWani project. Run 'waniwani mcp create <name>' first.",
1636
1799
  "NOT_IN_PROJECT"
1637
1800
  );
1638
1801
  }
1802
+ try {
1803
+ execSync3("git rev-parse --is-inside-work-tree", {
1804
+ cwd: projectRoot,
1805
+ stdio: "ignore"
1806
+ });
1807
+ } catch {
1808
+ throw new CLIError(
1809
+ "Not a git repository. Run 'waniwani mcp create <name>' or 'waniwani mcp clone <name>' to set up properly.",
1810
+ "NOT_GIT_REPO"
1811
+ );
1812
+ }
1813
+ const status = execSync3("git status --porcelain", {
1814
+ cwd: projectRoot,
1815
+ encoding: "utf-8"
1816
+ }).trim();
1817
+ if (!status) {
1818
+ if (json) {
1819
+ formatOutput({ success: true, message: "Nothing to publish" }, true);
1820
+ } else {
1821
+ console.log("Nothing to publish \u2014 no changes detected.");
1822
+ }
1823
+ return;
1824
+ }
1639
1825
  let message = options.message;
1640
1826
  if (!message) {
1641
1827
  message = await input({
@@ -1643,20 +1829,43 @@ var publishCommand = new Command14("publish").description("Push local files to G
1643
1829
  validate: (value) => value.trim() ? true : "Commit message is required"
1644
1830
  });
1645
1831
  }
1646
- const spinner = ora10("Collecting files...").start();
1647
- const files = await collectFiles(projectRoot);
1648
- if (files.length === 0) {
1649
- spinner.fail("No files to deploy");
1650
- return;
1651
- }
1652
- spinner.text = `Pushing ${files.length} files to GitHub...`;
1653
- const result = await api.post(
1654
- `/api/mcp/repositories/${mcpId}/deploy`,
1655
- { files, message }
1832
+ const spinner = ora11("Publishing...").start();
1833
+ const { cloneUrl } = await api.get(
1834
+ `/api/mcp/repositories/${mcpId}/clone-url`
1656
1835
  );
1657
- spinner.succeed(`Pushed to GitHub (${result.commitSha.slice(0, 7)})`);
1836
+ spinner.text = "Committing changes...";
1837
+ execSync3("git add -A", { cwd: projectRoot, stdio: "ignore" });
1838
+ execSync3(`git commit -m "${message.replace(/"/g, '\\"')}"`, {
1839
+ cwd: projectRoot,
1840
+ stdio: "ignore"
1841
+ });
1842
+ spinner.text = "Pushing to GitHub...";
1843
+ const originalUrl = execSync3("git remote get-url origin", {
1844
+ cwd: projectRoot,
1845
+ encoding: "utf-8"
1846
+ }).trim();
1847
+ try {
1848
+ execSync3(`git remote set-url origin "${cloneUrl}"`, {
1849
+ cwd: projectRoot,
1850
+ stdio: "ignore"
1851
+ });
1852
+ execSync3("git push origin HEAD", {
1853
+ cwd: projectRoot,
1854
+ stdio: "ignore"
1855
+ });
1856
+ } finally {
1857
+ execSync3(`git remote set-url origin "${originalUrl}"`, {
1858
+ cwd: projectRoot,
1859
+ stdio: "ignore"
1860
+ });
1861
+ }
1862
+ const commitSha = execSync3("git rev-parse HEAD", {
1863
+ cwd: projectRoot,
1864
+ encoding: "utf-8"
1865
+ }).trim();
1866
+ spinner.succeed(`Pushed to GitHub (${commitSha.slice(0, 7)})`);
1658
1867
  if (json) {
1659
- formatOutput(result, true);
1868
+ formatOutput({ commitSha, message }, true);
1660
1869
  } else {
1661
1870
  console.log();
1662
1871
  formatSuccess("Files pushed to GitHub!", false);
@@ -1671,9 +1880,9 @@ var publishCommand = new Command14("publish").description("Push local files to G
1671
1880
 
1672
1881
  // src/commands/mcp/run-command.ts
1673
1882
  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(
1883
+ import { Command as Command16 } from "commander";
1884
+ import ora12 from "ora";
1885
+ 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
1886
  "--timeout <ms>",
1678
1887
  "Command timeout in milliseconds (default: 30000, max: 300000)"
1679
1888
  ).action(async (cmd, args, options, command) => {
@@ -1683,7 +1892,7 @@ var runCommandCommand = new Command15("run-command").description("Run a command
1683
1892
  await requireMcpId(options.mcpId);
1684
1893
  const sessionId = await requireSessionId();
1685
1894
  const timeout = options.timeout ? Number.parseInt(options.timeout, 10) : void 0;
1686
- const spinner = ora11(`Running: ${cmd} ${args.join(" ")}`.trim()).start();
1895
+ const spinner = ora12(`Running: ${cmd} ${args.join(" ")}`.trim()).start();
1687
1896
  const result = await api.post(
1688
1897
  `/api/mcp/sessions/${sessionId}/commands`,
1689
1898
  {
@@ -1730,14 +1939,14 @@ var runCommandCommand = new Command15("run-command").description("Run a command
1730
1939
 
1731
1940
  // src/commands/mcp/status.ts
1732
1941
  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) => {
1942
+ import { Command as Command17 } from "commander";
1943
+ import ora13 from "ora";
1944
+ var statusCommand = new Command17("status").description("Show current MCP status").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
1736
1945
  const globalOptions = command.optsWithGlobals();
1737
1946
  const json = globalOptions.json ?? false;
1738
1947
  try {
1739
1948
  const mcpId = await requireMcpId(options.mcpId);
1740
- const spinner = ora12("Fetching MCP status...").start();
1949
+ const spinner = ora13("Fetching MCP status...").start();
1741
1950
  const result = await api.get(
1742
1951
  `/api/mcp/repositories/${mcpId}`
1743
1952
  );
@@ -1806,15 +2015,15 @@ var statusCommand = new Command16("status").description("Show current MCP status
1806
2015
  });
1807
2016
 
1808
2017
  // 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) => {
2018
+ import { Command as Command18 } from "commander";
2019
+ import ora14 from "ora";
2020
+ var stopCommand = new Command18("stop").description("Stop the development environment (sandbox + server)").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
1812
2021
  const globalOptions = command.optsWithGlobals();
1813
2022
  const json = globalOptions.json ?? false;
1814
2023
  try {
1815
2024
  await requireMcpId(options.mcpId);
1816
2025
  const sessionId = await requireSessionId();
1817
- const spinner = ora13("Stopping development environment...").start();
2026
+ const spinner = ora14("Stopping development environment...").start();
1818
2027
  try {
1819
2028
  await api.post(`/api/mcp/sessions/${sessionId}/server`, {
1820
2029
  action: "stop"
@@ -1838,9 +2047,9 @@ var stopCommand = new Command17("stop").description("Stop the development enviro
1838
2047
  });
1839
2048
 
1840
2049
  // 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) => {
2050
+ import { Command as Command19 } from "commander";
2051
+ import ora15 from "ora";
2052
+ var syncCommand = new Command19("sync").description("Pull template files to local project").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
1844
2053
  const globalOptions = command.optsWithGlobals();
1845
2054
  const json = globalOptions.json ?? false;
1846
2055
  try {
@@ -1848,11 +2057,11 @@ var syncCommand = new Command18("sync").description("Pull template files to loca
1848
2057
  const projectRoot = await findProjectRoot(process.cwd());
1849
2058
  if (!projectRoot) {
1850
2059
  throw new CLIError(
1851
- "Not in a WaniWani project. Run 'waniwani mcp init <name>' first.",
2060
+ "Not in a WaniWani project. Run 'waniwani mcp create <name>' first.",
1852
2061
  "NOT_IN_PROJECT"
1853
2062
  );
1854
2063
  }
1855
- const spinner = ora14("Pulling files...").start();
2064
+ const spinner = ora15("Pulling files...").start();
1856
2065
  const result = await pullFilesFromGithub(mcpId, projectRoot);
1857
2066
  spinner.succeed(`Pulled ${result.count} files`);
1858
2067
  if (json) {
@@ -1874,13 +2083,13 @@ var syncCommand = new Command18("sync").description("Pull template files to loca
1874
2083
  });
1875
2084
 
1876
2085
  // 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) => {
2086
+ import { Command as Command20 } from "commander";
2087
+ import ora16 from "ora";
2088
+ 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
2089
  const globalOptions = command.optsWithGlobals();
1881
2090
  const json = globalOptions.json ?? false;
1882
2091
  try {
1883
- const spinner = ora15("Fetching MCPs...").start();
2092
+ const spinner = ora16("Fetching MCPs...").start();
1884
2093
  const mcps = await api.get(
1885
2094
  "/api/mcp/repositories"
1886
2095
  );
@@ -1911,20 +2120,20 @@ var useCommand = new Command19("use").description("Select an MCP to use for subs
1911
2120
  });
1912
2121
 
1913
2122
  // 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);
2123
+ 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
2124
 
1916
2125
  // src/commands/org/index.ts
1917
- import { Command as Command23 } from "commander";
2126
+ import { Command as Command24 } from "commander";
1918
2127
 
1919
2128
  // src/commands/org/list.ts
1920
2129
  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) => {
2130
+ import { Command as Command22 } from "commander";
2131
+ import ora17 from "ora";
2132
+ var listCommand3 = new Command22("list").description("List your organizations").action(async (_, command) => {
1924
2133
  const globalOptions = command.optsWithGlobals();
1925
2134
  const json = globalOptions.json ?? false;
1926
2135
  try {
1927
- const spinner = ora16("Fetching organizations...").start();
2136
+ const spinner = ora17("Fetching organizations...").start();
1928
2137
  const result = await api.get("/api/oauth/orgs");
1929
2138
  spinner.stop();
1930
2139
  const { orgs, activeOrgId } = result;
@@ -1970,13 +2179,13 @@ var listCommand3 = new Command21("list").description("List your organizations").
1970
2179
  });
1971
2180
 
1972
2181
  // 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) => {
2182
+ import { Command as Command23 } from "commander";
2183
+ import ora18 from "ora";
2184
+ 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
2185
  const globalOptions = command.optsWithGlobals();
1977
2186
  const json = globalOptions.json ?? false;
1978
2187
  try {
1979
- const spinner = ora17("Fetching organizations...").start();
2188
+ const spinner = ora18("Fetching organizations...").start();
1980
2189
  const { orgs } = await api.get("/api/oauth/orgs");
1981
2190
  const org = orgs.find((o) => o.name === name || o.slug === name);
1982
2191
  if (!org) {
@@ -2009,12 +2218,12 @@ var switchCommand = new Command22("switch").description("Switch to a different o
2009
2218
  });
2010
2219
 
2011
2220
  // src/commands/org/index.ts
2012
- var orgCommand = new Command23("org").description("Organization management commands").addCommand(listCommand3).addCommand(switchCommand);
2221
+ var orgCommand = new Command24("org").description("Organization management commands").addCommand(listCommand3).addCommand(switchCommand);
2013
2222
 
2014
2223
  // src/cli.ts
2015
2224
  var require2 = createRequire(import.meta.url);
2016
2225
  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");
2226
+ 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
2227
  program.addCommand(loginCommand);
2019
2228
  program.addCommand(logoutCommand);
2020
2229
  program.addCommand(mcpCommand);