@waniwani/cli 0.0.23 → 0.0.24
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 +481 -207
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
|
-
import { Command as
|
|
4
|
+
import { Command as Command24 } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/commands/init.ts
|
|
7
7
|
import { existsSync } from "fs";
|
|
@@ -687,7 +687,7 @@ var logoutCommand = new Command3("logout").description("Log out from WaniWani").
|
|
|
687
687
|
});
|
|
688
688
|
|
|
689
689
|
// src/commands/mcp/index.ts
|
|
690
|
-
import { Command as
|
|
690
|
+
import { Command as Command19 } from "commander";
|
|
691
691
|
|
|
692
692
|
// src/commands/mcp/create.ts
|
|
693
693
|
import { Command as Command4 } from "commander";
|
|
@@ -730,11 +730,31 @@ async function request(method, path, options) {
|
|
|
730
730
|
if (response.status === 204) {
|
|
731
731
|
return void 0;
|
|
732
732
|
}
|
|
733
|
-
|
|
733
|
+
let data;
|
|
734
|
+
let rawBody;
|
|
735
|
+
try {
|
|
736
|
+
rawBody = await response.text();
|
|
737
|
+
data = JSON.parse(rawBody);
|
|
738
|
+
} catch {
|
|
739
|
+
throw new ApiError(
|
|
740
|
+
rawBody || `Request failed with status ${response.status}`,
|
|
741
|
+
"API_ERROR",
|
|
742
|
+
response.status,
|
|
743
|
+
{ statusText: response.statusText }
|
|
744
|
+
);
|
|
745
|
+
}
|
|
734
746
|
if (!response.ok || data.error) {
|
|
735
|
-
const
|
|
736
|
-
|
|
737
|
-
|
|
747
|
+
const errorMessage = data.error?.message || data.message || data.error || rawBody || `Request failed with status ${response.status}`;
|
|
748
|
+
const errorCode = data.error?.code || data.code || "API_ERROR";
|
|
749
|
+
const errorDetails = {
|
|
750
|
+
...data.error?.details,
|
|
751
|
+
statusText: response.statusText,
|
|
752
|
+
...data.error ? {} : { rawResponse: data }
|
|
753
|
+
};
|
|
754
|
+
const error = {
|
|
755
|
+
code: errorCode,
|
|
756
|
+
message: errorMessage,
|
|
757
|
+
details: errorDetails
|
|
738
758
|
};
|
|
739
759
|
if (response.status === 401) {
|
|
740
760
|
const refreshed = await auth.tryRefreshToken();
|
|
@@ -794,10 +814,41 @@ var createCommand = new Command4("create").description("Create a new MCP sandbox
|
|
|
794
814
|
}
|
|
795
815
|
});
|
|
796
816
|
|
|
797
|
-
// src/commands/mcp/
|
|
817
|
+
// src/commands/mcp/delete.ts
|
|
798
818
|
import { Command as Command5 } from "commander";
|
|
799
819
|
import ora3 from "ora";
|
|
800
|
-
var
|
|
820
|
+
var deleteCommand = new Command5("delete").description("Delete the MCP sandbox").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
|
|
821
|
+
const globalOptions = command.optsWithGlobals();
|
|
822
|
+
const json = globalOptions.json ?? false;
|
|
823
|
+
try {
|
|
824
|
+
let mcpId = options.mcpId;
|
|
825
|
+
if (!mcpId) {
|
|
826
|
+
mcpId = await config.getMcpId();
|
|
827
|
+
if (!mcpId) {
|
|
828
|
+
throw new McpError("No active MCP. Use --mcp-id to specify one.");
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
const spinner = ora3("Deleting MCP sandbox...").start();
|
|
832
|
+
await api.delete(`/api/mcp/sandboxes/${mcpId}`);
|
|
833
|
+
spinner.succeed("MCP sandbox deleted");
|
|
834
|
+
if (await config.getMcpId() === mcpId) {
|
|
835
|
+
await config.setMcpId(null);
|
|
836
|
+
}
|
|
837
|
+
if (json) {
|
|
838
|
+
formatOutput({ deleted: mcpId }, true);
|
|
839
|
+
} else {
|
|
840
|
+
formatSuccess("MCP sandbox deleted and cleaned up.", false);
|
|
841
|
+
}
|
|
842
|
+
} catch (error) {
|
|
843
|
+
handleError(error, json);
|
|
844
|
+
process.exit(1);
|
|
845
|
+
}
|
|
846
|
+
});
|
|
847
|
+
|
|
848
|
+
// src/commands/mcp/deploy.ts
|
|
849
|
+
import { Command as Command6 } from "commander";
|
|
850
|
+
import ora4 from "ora";
|
|
851
|
+
var deployCommand = new Command6("deploy").description("Deploy MCP server to GitHub + Vercel from sandbox").option("--repo <name>", "GitHub repository name").option("--org <name>", "GitHub organization").option("--private", "Create private repository").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
|
|
801
852
|
const globalOptions = command.optsWithGlobals();
|
|
802
853
|
const json = globalOptions.json ?? false;
|
|
803
854
|
try {
|
|
@@ -810,7 +861,7 @@ var deployCommand = new Command5("deploy").description("Deploy MCP server to Git
|
|
|
810
861
|
);
|
|
811
862
|
}
|
|
812
863
|
}
|
|
813
|
-
const spinner =
|
|
864
|
+
const spinner = ora4("Deploying to GitHub...").start();
|
|
814
865
|
const result = await api.post(
|
|
815
866
|
`/api/admin/mcps/${mcpId}/deploy`,
|
|
816
867
|
{
|
|
@@ -841,71 +892,14 @@ var deployCommand = new Command5("deploy").description("Deploy MCP server to Git
|
|
|
841
892
|
}
|
|
842
893
|
});
|
|
843
894
|
|
|
844
|
-
// src/commands/mcp/
|
|
845
|
-
import
|
|
846
|
-
import { Command as Command6 } from "commander";
|
|
847
|
-
import ora4 from "ora";
|
|
848
|
-
var listCommand = new Command6("list").description("List all MCPs in your organization").option("--all", "Include stopped/expired MCPs").action(async (options, command) => {
|
|
849
|
-
const globalOptions = command.optsWithGlobals();
|
|
850
|
-
const json = globalOptions.json ?? false;
|
|
851
|
-
try {
|
|
852
|
-
const spinner = ora4("Fetching MCPs...").start();
|
|
853
|
-
const mcps = await api.get(
|
|
854
|
-
`/api/mcp/sandboxes${options.all ? "?all=true" : ""}`
|
|
855
|
-
);
|
|
856
|
-
spinner.stop();
|
|
857
|
-
const activeMcpId = await config.getMcpId();
|
|
858
|
-
if (json) {
|
|
859
|
-
formatOutput(
|
|
860
|
-
{
|
|
861
|
-
mcps: mcps.map((m) => ({
|
|
862
|
-
...m,
|
|
863
|
-
isActive: m.id === activeMcpId
|
|
864
|
-
})),
|
|
865
|
-
activeMcpId
|
|
866
|
-
},
|
|
867
|
-
true
|
|
868
|
-
);
|
|
869
|
-
} else {
|
|
870
|
-
if (mcps.length === 0) {
|
|
871
|
-
console.log("No MCPs found.");
|
|
872
|
-
console.log("\nCreate a new MCP sandbox: waniwani mcp create <name>");
|
|
873
|
-
return;
|
|
874
|
-
}
|
|
875
|
-
console.log(chalk4.bold("\nMCPs:\n"));
|
|
876
|
-
const rows = mcps.map((m) => {
|
|
877
|
-
const isActive = m.id === activeMcpId;
|
|
878
|
-
const statusColor = m.status === "active" ? chalk4.green : m.status === "stopped" ? chalk4.red : chalk4.yellow;
|
|
879
|
-
return [
|
|
880
|
-
isActive ? chalk4.cyan(`* ${m.id.slice(0, 8)}`) : ` ${m.id.slice(0, 8)}`,
|
|
881
|
-
m.name,
|
|
882
|
-
statusColor(m.status),
|
|
883
|
-
m.previewUrl,
|
|
884
|
-
m.createdAt ? new Date(m.createdAt).toLocaleString() : "N/A"
|
|
885
|
-
];
|
|
886
|
-
});
|
|
887
|
-
formatTable(
|
|
888
|
-
["ID", "Name", "Status", "Preview URL", "Created"],
|
|
889
|
-
rows,
|
|
890
|
-
false
|
|
891
|
-
);
|
|
892
|
-
console.log();
|
|
893
|
-
if (activeMcpId) {
|
|
894
|
-
console.log(`Active MCP: ${chalk4.cyan(activeMcpId.slice(0, 8))}`);
|
|
895
|
-
}
|
|
896
|
-
console.log("\nSelect an MCP: waniwani mcp use <name>");
|
|
897
|
-
}
|
|
898
|
-
} catch (error) {
|
|
899
|
-
handleError(error, json);
|
|
900
|
-
process.exit(1);
|
|
901
|
-
}
|
|
902
|
-
});
|
|
895
|
+
// src/commands/mcp/file/index.ts
|
|
896
|
+
import { Command as Command10 } from "commander";
|
|
903
897
|
|
|
904
|
-
// src/commands/mcp/list
|
|
905
|
-
import
|
|
898
|
+
// src/commands/mcp/file/list.ts
|
|
899
|
+
import chalk4 from "chalk";
|
|
906
900
|
import { Command as Command7 } from "commander";
|
|
907
901
|
import ora5 from "ora";
|
|
908
|
-
var
|
|
902
|
+
var listCommand = new Command7("list").description("List files in the MCP sandbox").argument("[path]", "Directory path (defaults to /app)", "/app").option("--mcp-id <id>", "Specific MCP ID").action(async (path, options, command) => {
|
|
909
903
|
const globalOptions = command.optsWithGlobals();
|
|
910
904
|
const json = globalOptions.json ?? false;
|
|
911
905
|
try {
|
|
@@ -926,15 +920,15 @@ var listFilesCommand = new Command7("list-files").description("List files in the
|
|
|
926
920
|
if (json) {
|
|
927
921
|
formatOutput(result, true);
|
|
928
922
|
} else {
|
|
929
|
-
console.log(
|
|
923
|
+
console.log(chalk4.bold(`
|
|
930
924
|
Directory: ${result.path}
|
|
931
925
|
`));
|
|
932
926
|
if (result.entries.length === 0) {
|
|
933
927
|
console.log(" (empty)");
|
|
934
928
|
} else {
|
|
935
929
|
const rows = result.entries.map((entry) => {
|
|
936
|
-
const name = entry.type === "directory" ?
|
|
937
|
-
const size = entry.type === "directory" ?
|
|
930
|
+
const name = entry.type === "directory" ? chalk4.blue(`${entry.name}/`) : entry.name;
|
|
931
|
+
const size = entry.type === "directory" ? chalk4.gray("<dir>") : formatSize(entry.size);
|
|
938
932
|
return [name, size];
|
|
939
933
|
});
|
|
940
934
|
formatTable(["Name", "Size"], rows, false);
|
|
@@ -953,11 +947,11 @@ function formatSize(bytes) {
|
|
|
953
947
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
954
948
|
}
|
|
955
949
|
|
|
956
|
-
// src/commands/mcp/read
|
|
950
|
+
// src/commands/mcp/file/read.ts
|
|
957
951
|
import { writeFile as writeFile4 } from "fs/promises";
|
|
958
952
|
import { Command as Command8 } from "commander";
|
|
959
953
|
import ora6 from "ora";
|
|
960
|
-
var
|
|
954
|
+
var readCommand = new Command8("read").description("Read a file from the MCP sandbox").argument("<path>", "Path in sandbox (e.g., /app/src/index.ts)").option("--mcp-id <id>", "Specific MCP ID").option("--output <file>", "Write to local file instead of stdout").option("--base64", "Output as base64 (for binary files)").action(async (path, options, command) => {
|
|
961
955
|
const globalOptions = command.optsWithGlobals();
|
|
962
956
|
const json = globalOptions.json ?? false;
|
|
963
957
|
try {
|
|
@@ -1001,11 +995,281 @@ var readFileCommand = new Command8("read-file").description("Read a file from th
|
|
|
1001
995
|
}
|
|
1002
996
|
});
|
|
1003
997
|
|
|
1004
|
-
// src/commands/mcp/
|
|
1005
|
-
import
|
|
998
|
+
// src/commands/mcp/file/write.ts
|
|
999
|
+
import { readFile as readFile3 } from "fs/promises";
|
|
1006
1000
|
import { Command as Command9 } from "commander";
|
|
1007
1001
|
import ora7 from "ora";
|
|
1008
|
-
var
|
|
1002
|
+
var writeCommand = new Command9("write").description("Write a file to the MCP sandbox").argument("<path>", "Path in sandbox (e.g., /app/src/index.ts)").option("--mcp-id <id>", "Specific MCP ID").option("--content <content>", "Content to write").option("--file <localFile>", "Local file to upload").option("--base64", "Treat content as base64 encoded").action(async (path, options, command) => {
|
|
1003
|
+
const globalOptions = command.optsWithGlobals();
|
|
1004
|
+
const json = globalOptions.json ?? false;
|
|
1005
|
+
try {
|
|
1006
|
+
let mcpId = options.mcpId;
|
|
1007
|
+
if (!mcpId) {
|
|
1008
|
+
mcpId = await config.getMcpId();
|
|
1009
|
+
if (!mcpId) {
|
|
1010
|
+
throw new McpError(
|
|
1011
|
+
"No active MCP. Run 'waniwani mcp create <name>' or 'waniwani mcp use <name>'."
|
|
1012
|
+
);
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
let content;
|
|
1016
|
+
let encoding = "utf8";
|
|
1017
|
+
if (options.content) {
|
|
1018
|
+
content = options.content;
|
|
1019
|
+
if (options.base64) {
|
|
1020
|
+
encoding = "base64";
|
|
1021
|
+
}
|
|
1022
|
+
} else if (options.file) {
|
|
1023
|
+
const fileBuffer = await readFile3(options.file);
|
|
1024
|
+
if (options.base64) {
|
|
1025
|
+
content = fileBuffer.toString("base64");
|
|
1026
|
+
encoding = "base64";
|
|
1027
|
+
} else {
|
|
1028
|
+
content = fileBuffer.toString("utf8");
|
|
1029
|
+
}
|
|
1030
|
+
} else {
|
|
1031
|
+
throw new CLIError(
|
|
1032
|
+
"Either --content or --file is required",
|
|
1033
|
+
"MISSING_CONTENT"
|
|
1034
|
+
);
|
|
1035
|
+
}
|
|
1036
|
+
const spinner = ora7(`Writing ${path}...`).start();
|
|
1037
|
+
const result = await api.post(
|
|
1038
|
+
`/api/mcp/sandboxes/${mcpId}/files`,
|
|
1039
|
+
{
|
|
1040
|
+
files: [{ path, content, encoding }]
|
|
1041
|
+
}
|
|
1042
|
+
);
|
|
1043
|
+
spinner.succeed(`Wrote ${path}`);
|
|
1044
|
+
if (json) {
|
|
1045
|
+
formatOutput(result, true);
|
|
1046
|
+
} else {
|
|
1047
|
+
formatSuccess(`File written: ${path}`, false);
|
|
1048
|
+
}
|
|
1049
|
+
} catch (error) {
|
|
1050
|
+
handleError(error, json);
|
|
1051
|
+
process.exit(1);
|
|
1052
|
+
}
|
|
1053
|
+
});
|
|
1054
|
+
|
|
1055
|
+
// src/commands/mcp/file/index.ts
|
|
1056
|
+
var fileCommand = new Command10("file").description("File operations in MCP sandbox").addCommand(readCommand).addCommand(writeCommand).addCommand(listCommand);
|
|
1057
|
+
|
|
1058
|
+
// src/commands/mcp/list.ts
|
|
1059
|
+
import chalk5 from "chalk";
|
|
1060
|
+
import { Command as Command11 } from "commander";
|
|
1061
|
+
import ora8 from "ora";
|
|
1062
|
+
var listCommand2 = new Command11("list").description("List all MCPs in your organization").option("--all", "Include stopped/expired MCPs").action(async (options, command) => {
|
|
1063
|
+
const globalOptions = command.optsWithGlobals();
|
|
1064
|
+
const json = globalOptions.json ?? false;
|
|
1065
|
+
try {
|
|
1066
|
+
const spinner = ora8("Fetching MCPs...").start();
|
|
1067
|
+
const mcps = await api.get(
|
|
1068
|
+
`/api/mcp/sandboxes${options.all ? "?all=true" : ""}`
|
|
1069
|
+
);
|
|
1070
|
+
spinner.stop();
|
|
1071
|
+
const activeMcpId = await config.getMcpId();
|
|
1072
|
+
if (json) {
|
|
1073
|
+
formatOutput(
|
|
1074
|
+
{
|
|
1075
|
+
mcps: mcps.map((m) => ({
|
|
1076
|
+
...m,
|
|
1077
|
+
isActive: m.id === activeMcpId
|
|
1078
|
+
})),
|
|
1079
|
+
activeMcpId
|
|
1080
|
+
},
|
|
1081
|
+
true
|
|
1082
|
+
);
|
|
1083
|
+
} else {
|
|
1084
|
+
if (mcps.length === 0) {
|
|
1085
|
+
console.log("No MCPs found.");
|
|
1086
|
+
console.log("\nCreate a new MCP sandbox: waniwani mcp create <name>");
|
|
1087
|
+
return;
|
|
1088
|
+
}
|
|
1089
|
+
console.log(chalk5.bold("\nMCPs:\n"));
|
|
1090
|
+
const rows = mcps.map((m) => {
|
|
1091
|
+
const isActive = m.id === activeMcpId;
|
|
1092
|
+
const statusColor = m.status === "active" ? chalk5.green : m.status === "stopped" ? chalk5.red : chalk5.yellow;
|
|
1093
|
+
return [
|
|
1094
|
+
isActive ? chalk5.cyan(`* ${m.id.slice(0, 8)}`) : ` ${m.id.slice(0, 8)}`,
|
|
1095
|
+
m.name,
|
|
1096
|
+
statusColor(m.status),
|
|
1097
|
+
m.previewUrl,
|
|
1098
|
+
m.createdAt ? new Date(m.createdAt).toLocaleString() : "N/A"
|
|
1099
|
+
];
|
|
1100
|
+
});
|
|
1101
|
+
formatTable(
|
|
1102
|
+
["ID", "Name", "Status", "Preview URL", "Created"],
|
|
1103
|
+
rows,
|
|
1104
|
+
false
|
|
1105
|
+
);
|
|
1106
|
+
console.log();
|
|
1107
|
+
if (activeMcpId) {
|
|
1108
|
+
console.log(`Active MCP: ${chalk5.cyan(activeMcpId.slice(0, 8))}`);
|
|
1109
|
+
}
|
|
1110
|
+
console.log("\nSelect an MCP: waniwani mcp use <name>");
|
|
1111
|
+
}
|
|
1112
|
+
} catch (error) {
|
|
1113
|
+
handleError(error, json);
|
|
1114
|
+
process.exit(1);
|
|
1115
|
+
}
|
|
1116
|
+
});
|
|
1117
|
+
|
|
1118
|
+
// src/commands/mcp/logs.ts
|
|
1119
|
+
import chalk6 from "chalk";
|
|
1120
|
+
import { Command as Command12 } from "commander";
|
|
1121
|
+
import ora9 from "ora";
|
|
1122
|
+
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) => {
|
|
1123
|
+
const globalOptions = command.optsWithGlobals();
|
|
1124
|
+
const json = globalOptions.json ?? false;
|
|
1125
|
+
let reader;
|
|
1126
|
+
const cleanup = () => {
|
|
1127
|
+
if (reader) {
|
|
1128
|
+
reader.cancel().catch(() => {
|
|
1129
|
+
});
|
|
1130
|
+
}
|
|
1131
|
+
process.exit(0);
|
|
1132
|
+
};
|
|
1133
|
+
process.on("SIGINT", cleanup);
|
|
1134
|
+
process.on("SIGTERM", cleanup);
|
|
1135
|
+
try {
|
|
1136
|
+
let mcpId = options.mcpId;
|
|
1137
|
+
if (!mcpId) {
|
|
1138
|
+
mcpId = await config.getMcpId();
|
|
1139
|
+
if (!mcpId) {
|
|
1140
|
+
throw new McpError(
|
|
1141
|
+
"No active MCP. Run 'waniwani mcp create <name>' or 'waniwani mcp use <name>'."
|
|
1142
|
+
);
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
const token = await auth.getAccessToken();
|
|
1146
|
+
if (!token) {
|
|
1147
|
+
throw new AuthError(
|
|
1148
|
+
"Not logged in. Run 'waniwani login' to authenticate."
|
|
1149
|
+
);
|
|
1150
|
+
}
|
|
1151
|
+
let cmdId = cmdIdArg;
|
|
1152
|
+
if (!cmdId) {
|
|
1153
|
+
const spinner = ora9("Getting server status...").start();
|
|
1154
|
+
const status = await api.post(
|
|
1155
|
+
`/api/mcp/sandboxes/${mcpId}/server`,
|
|
1156
|
+
{ action: "status" }
|
|
1157
|
+
);
|
|
1158
|
+
spinner.stop();
|
|
1159
|
+
if (!status.running || !status.cmdId) {
|
|
1160
|
+
throw new McpError(
|
|
1161
|
+
"No server is running. Run 'waniwani mcp start' first."
|
|
1162
|
+
);
|
|
1163
|
+
}
|
|
1164
|
+
cmdId = status.cmdId;
|
|
1165
|
+
}
|
|
1166
|
+
const baseUrl = await api.getBaseUrl();
|
|
1167
|
+
const streamParam = options.follow ? "?stream=true" : "";
|
|
1168
|
+
const url = `${baseUrl}/api/mcp/sandboxes/${mcpId}/commands/${cmdId}${streamParam}`;
|
|
1169
|
+
if (!json) {
|
|
1170
|
+
console.log(chalk6.gray(`Streaming logs for command ${cmdId}...`));
|
|
1171
|
+
console.log(chalk6.gray("Press Ctrl+C to stop\n"));
|
|
1172
|
+
}
|
|
1173
|
+
const response = await fetch(url, {
|
|
1174
|
+
method: "GET",
|
|
1175
|
+
headers: {
|
|
1176
|
+
Authorization: `Bearer ${token}`,
|
|
1177
|
+
Accept: options.follow ? "text/event-stream" : "application/json"
|
|
1178
|
+
}
|
|
1179
|
+
});
|
|
1180
|
+
if (!response.ok) {
|
|
1181
|
+
const error = await response.json().catch(() => ({ message: response.statusText }));
|
|
1182
|
+
throw new Error(
|
|
1183
|
+
error.message || `Request failed with status ${response.status}`
|
|
1184
|
+
);
|
|
1185
|
+
}
|
|
1186
|
+
if (!options.follow) {
|
|
1187
|
+
const data = await response.json();
|
|
1188
|
+
if (json) {
|
|
1189
|
+
formatOutput(data, true);
|
|
1190
|
+
} else {
|
|
1191
|
+
if (data.stdout) {
|
|
1192
|
+
process.stdout.write(data.stdout);
|
|
1193
|
+
}
|
|
1194
|
+
if (data.stderr) {
|
|
1195
|
+
process.stderr.write(chalk6.red(data.stderr));
|
|
1196
|
+
}
|
|
1197
|
+
if (data.exitCode !== void 0) {
|
|
1198
|
+
console.log(chalk6.gray(`
|
|
1199
|
+
Exit code: ${data.exitCode}`));
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
return;
|
|
1203
|
+
}
|
|
1204
|
+
reader = response.body?.getReader();
|
|
1205
|
+
if (!reader) {
|
|
1206
|
+
throw new Error("No response body");
|
|
1207
|
+
}
|
|
1208
|
+
const decoder = new TextDecoder();
|
|
1209
|
+
let buffer = "";
|
|
1210
|
+
const collectedLogs = [];
|
|
1211
|
+
while (true) {
|
|
1212
|
+
const { done, value } = await reader.read();
|
|
1213
|
+
if (done) break;
|
|
1214
|
+
buffer += decoder.decode(value, { stream: true });
|
|
1215
|
+
const lines = buffer.split("\n");
|
|
1216
|
+
buffer = lines.pop() || "";
|
|
1217
|
+
for (const line of lines) {
|
|
1218
|
+
if (line.startsWith("event: ")) {
|
|
1219
|
+
continue;
|
|
1220
|
+
}
|
|
1221
|
+
if (line.startsWith("data: ")) {
|
|
1222
|
+
const data = line.slice(6);
|
|
1223
|
+
if (!data || data === "[DONE]") continue;
|
|
1224
|
+
try {
|
|
1225
|
+
const event = JSON.parse(data);
|
|
1226
|
+
collectedLogs.push(event);
|
|
1227
|
+
if (json) {
|
|
1228
|
+
continue;
|
|
1229
|
+
}
|
|
1230
|
+
if (event.cmdId) {
|
|
1231
|
+
continue;
|
|
1232
|
+
}
|
|
1233
|
+
if (event.stream && event.data !== void 0) {
|
|
1234
|
+
if (event.stream === "stdout") {
|
|
1235
|
+
process.stdout.write(event.data);
|
|
1236
|
+
} else if (event.stream === "stderr") {
|
|
1237
|
+
process.stderr.write(chalk6.red(event.data));
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
if (event.exitCode !== void 0) {
|
|
1241
|
+
const exitColor = event.exitCode === 0 ? chalk6.green : chalk6.red;
|
|
1242
|
+
console.log(
|
|
1243
|
+
exitColor(`
|
|
1244
|
+
Process exited with code ${event.exitCode}`)
|
|
1245
|
+
);
|
|
1246
|
+
}
|
|
1247
|
+
if (event.error) {
|
|
1248
|
+
console.error(chalk6.red(`
|
|
1249
|
+
Error: ${event.error}`));
|
|
1250
|
+
}
|
|
1251
|
+
} catch {
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
if (json) {
|
|
1257
|
+
formatOutput(collectedLogs, true);
|
|
1258
|
+
}
|
|
1259
|
+
} catch (error) {
|
|
1260
|
+
handleError(error, json);
|
|
1261
|
+
process.exit(1);
|
|
1262
|
+
} finally {
|
|
1263
|
+
process.off("SIGINT", cleanup);
|
|
1264
|
+
process.off("SIGTERM", cleanup);
|
|
1265
|
+
}
|
|
1266
|
+
});
|
|
1267
|
+
|
|
1268
|
+
// src/commands/mcp/run-command.ts
|
|
1269
|
+
import chalk7 from "chalk";
|
|
1270
|
+
import { Command as Command13 } from "commander";
|
|
1271
|
+
import ora10 from "ora";
|
|
1272
|
+
var runCommandCommand = new Command13("run-command").description("Run a command in the MCP sandbox").argument("<command>", "Command to run").argument("[args...]", "Command arguments").option("--mcp-id <id>", "Specific MCP ID").option("--cwd <path>", "Working directory").option(
|
|
1009
1273
|
"--timeout <ms>",
|
|
1010
1274
|
"Command timeout in milliseconds (default: 30000, max: 300000)"
|
|
1011
1275
|
).action(async (cmd, args, options, command) => {
|
|
@@ -1022,7 +1286,7 @@ var runCommandCommand = new Command9("run-command").description("Run a command i
|
|
|
1022
1286
|
}
|
|
1023
1287
|
}
|
|
1024
1288
|
const timeout = options.timeout ? Number.parseInt(options.timeout, 10) : void 0;
|
|
1025
|
-
const spinner =
|
|
1289
|
+
const spinner = ora10(`Running: ${cmd} ${args.join(" ")}`.trim()).start();
|
|
1026
1290
|
const result = await api.post(
|
|
1027
1291
|
`/api/mcp/sandboxes/${mcpId}/command`,
|
|
1028
1292
|
{
|
|
@@ -1037,7 +1301,7 @@ var runCommandCommand = new Command9("run-command").description("Run a command i
|
|
|
1037
1301
|
formatOutput(result, true);
|
|
1038
1302
|
} else {
|
|
1039
1303
|
const cmdLine = [cmd, ...args].join(" ");
|
|
1040
|
-
console.log(
|
|
1304
|
+
console.log(chalk7.gray(`$ ${cmdLine}`));
|
|
1041
1305
|
console.log();
|
|
1042
1306
|
if (result.stdout) {
|
|
1043
1307
|
process.stdout.write(result.stdout);
|
|
@@ -1046,16 +1310,16 @@ var runCommandCommand = new Command9("run-command").description("Run a command i
|
|
|
1046
1310
|
}
|
|
1047
1311
|
}
|
|
1048
1312
|
if (result.stderr) {
|
|
1049
|
-
process.stderr.write(
|
|
1313
|
+
process.stderr.write(chalk7.red(result.stderr));
|
|
1050
1314
|
if (!result.stderr.endsWith("\n")) {
|
|
1051
1315
|
process.stderr.write("\n");
|
|
1052
1316
|
}
|
|
1053
1317
|
}
|
|
1054
1318
|
console.log();
|
|
1055
|
-
const exitColor = result.exitCode === 0 ?
|
|
1319
|
+
const exitColor = result.exitCode === 0 ? chalk7.green : chalk7.red;
|
|
1056
1320
|
console.log(
|
|
1057
1321
|
exitColor(`Exit code: ${result.exitCode}`),
|
|
1058
|
-
|
|
1322
|
+
chalk7.gray(`(${(result.duration / 1e3).toFixed(2)}s)`)
|
|
1059
1323
|
);
|
|
1060
1324
|
}
|
|
1061
1325
|
if (result.exitCode !== 0) {
|
|
@@ -1067,11 +1331,56 @@ var runCommandCommand = new Command9("run-command").description("Run a command i
|
|
|
1067
1331
|
}
|
|
1068
1332
|
});
|
|
1069
1333
|
|
|
1334
|
+
// src/commands/mcp/start.ts
|
|
1335
|
+
import chalk8 from "chalk";
|
|
1336
|
+
import { Command as Command14 } from "commander";
|
|
1337
|
+
import ora11 from "ora";
|
|
1338
|
+
var startCommand = new Command14("start").description("Start the MCP server (npm run dev)").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
|
|
1339
|
+
const globalOptions = command.optsWithGlobals();
|
|
1340
|
+
const json = globalOptions.json ?? false;
|
|
1341
|
+
try {
|
|
1342
|
+
let mcpId = options.mcpId;
|
|
1343
|
+
if (!mcpId) {
|
|
1344
|
+
mcpId = await config.getMcpId();
|
|
1345
|
+
if (!mcpId) {
|
|
1346
|
+
throw new McpError(
|
|
1347
|
+
"No active MCP. Run 'waniwani mcp create <name>' or 'waniwani mcp use <name>'."
|
|
1348
|
+
);
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
const spinner = ora11("Starting MCP server...").start();
|
|
1352
|
+
const result = await api.post(
|
|
1353
|
+
`/api/mcp/sandboxes/${mcpId}/server`,
|
|
1354
|
+
{ action: "start" }
|
|
1355
|
+
);
|
|
1356
|
+
spinner.succeed("MCP server started");
|
|
1357
|
+
if (json) {
|
|
1358
|
+
formatOutput(result, true);
|
|
1359
|
+
} else {
|
|
1360
|
+
console.log();
|
|
1361
|
+
formatList(
|
|
1362
|
+
[
|
|
1363
|
+
{ label: "Command ID", value: result.cmdId },
|
|
1364
|
+
{ label: "Preview URL", value: chalk8.cyan(result.previewUrl) }
|
|
1365
|
+
],
|
|
1366
|
+
false
|
|
1367
|
+
);
|
|
1368
|
+
console.log();
|
|
1369
|
+
console.log(
|
|
1370
|
+
chalk8.gray("Run 'waniwani mcp logs' to stream server output")
|
|
1371
|
+
);
|
|
1372
|
+
}
|
|
1373
|
+
} catch (error) {
|
|
1374
|
+
handleError(error, json);
|
|
1375
|
+
process.exit(1);
|
|
1376
|
+
}
|
|
1377
|
+
});
|
|
1378
|
+
|
|
1070
1379
|
// src/commands/mcp/status.ts
|
|
1071
|
-
import
|
|
1072
|
-
import { Command as
|
|
1073
|
-
import
|
|
1074
|
-
var statusCommand = new
|
|
1380
|
+
import chalk9 from "chalk";
|
|
1381
|
+
import { Command as Command15 } from "commander";
|
|
1382
|
+
import ora12 from "ora";
|
|
1383
|
+
var statusCommand = new Command15("status").description("Show current MCP sandbox status").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
|
|
1075
1384
|
const globalOptions = command.optsWithGlobals();
|
|
1076
1385
|
const json = globalOptions.json ?? false;
|
|
1077
1386
|
try {
|
|
@@ -1084,13 +1393,24 @@ var statusCommand = new Command10("status").description("Show current MCP sandbo
|
|
|
1084
1393
|
);
|
|
1085
1394
|
}
|
|
1086
1395
|
}
|
|
1087
|
-
const spinner =
|
|
1088
|
-
const result = await
|
|
1396
|
+
const spinner = ora12("Fetching MCP status...").start();
|
|
1397
|
+
const [result, serverStatus] = await Promise.all([
|
|
1398
|
+
api.get(`/api/mcp/sandboxes/${mcpId}`),
|
|
1399
|
+
api.post(`/api/mcp/sandboxes/${mcpId}/server`, {
|
|
1400
|
+
action: "status"
|
|
1401
|
+
}).catch(() => ({
|
|
1402
|
+
running: false,
|
|
1403
|
+
cmdId: void 0,
|
|
1404
|
+
previewUrl: void 0
|
|
1405
|
+
}))
|
|
1406
|
+
]);
|
|
1089
1407
|
spinner.stop();
|
|
1090
1408
|
if (json) {
|
|
1091
|
-
formatOutput(result, true);
|
|
1409
|
+
formatOutput({ ...result, server: serverStatus }, true);
|
|
1092
1410
|
} else {
|
|
1093
|
-
const statusColor = result.status === "active" ?
|
|
1411
|
+
const statusColor = result.status === "active" ? chalk9.green : chalk9.red;
|
|
1412
|
+
const serverRunning = serverStatus.running;
|
|
1413
|
+
const serverStatusColor = serverRunning ? chalk9.green : chalk9.yellow;
|
|
1094
1414
|
formatList(
|
|
1095
1415
|
[
|
|
1096
1416
|
{ label: "MCP ID", value: result.id },
|
|
@@ -1098,6 +1418,11 @@ var statusCommand = new Command10("status").description("Show current MCP sandbo
|
|
|
1098
1418
|
{ label: "Status", value: statusColor(result.status) },
|
|
1099
1419
|
{ label: "Sandbox ID", value: result.sandboxId },
|
|
1100
1420
|
{ label: "Preview URL", value: result.previewUrl },
|
|
1421
|
+
{
|
|
1422
|
+
label: "Server",
|
|
1423
|
+
value: serverStatusColor(serverRunning ? "Running" : "Stopped")
|
|
1424
|
+
},
|
|
1425
|
+
...serverStatus.cmdId ? [{ label: "Server Cmd ID", value: serverStatus.cmdId }] : [],
|
|
1101
1426
|
{ label: "Created", value: result.createdAt },
|
|
1102
1427
|
{ label: "Expires", value: result.expiresAt ?? "N/A" }
|
|
1103
1428
|
],
|
|
@@ -1111,9 +1436,9 @@ var statusCommand = new Command10("status").description("Show current MCP sandbo
|
|
|
1111
1436
|
});
|
|
1112
1437
|
|
|
1113
1438
|
// src/commands/mcp/stop.ts
|
|
1114
|
-
import { Command as
|
|
1115
|
-
import
|
|
1116
|
-
var stopCommand = new
|
|
1439
|
+
import { Command as Command16 } from "commander";
|
|
1440
|
+
import ora13 from "ora";
|
|
1441
|
+
var stopCommand = new Command16("stop").description("Stop the MCP server process").option("--mcp-id <id>", "Specific MCP ID").action(async (options, command) => {
|
|
1117
1442
|
const globalOptions = command.optsWithGlobals();
|
|
1118
1443
|
const json = globalOptions.json ?? false;
|
|
1119
1444
|
try {
|
|
@@ -1121,19 +1446,25 @@ var stopCommand = new Command11("stop").description("Stop and clean up the MCP s
|
|
|
1121
1446
|
if (!mcpId) {
|
|
1122
1447
|
mcpId = await config.getMcpId();
|
|
1123
1448
|
if (!mcpId) {
|
|
1124
|
-
throw new McpError(
|
|
1449
|
+
throw new McpError(
|
|
1450
|
+
"No active MCP. Run 'waniwani mcp create <name>' or 'waniwani mcp use <name>'."
|
|
1451
|
+
);
|
|
1125
1452
|
}
|
|
1126
1453
|
}
|
|
1127
|
-
const spinner =
|
|
1128
|
-
await api.
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1454
|
+
const spinner = ora13("Stopping MCP server...").start();
|
|
1455
|
+
const result = await api.post(
|
|
1456
|
+
`/api/mcp/sandboxes/${mcpId}/server`,
|
|
1457
|
+
{ action: "stop" }
|
|
1458
|
+
);
|
|
1459
|
+
if (result.stopped) {
|
|
1460
|
+
spinner.succeed("MCP server stopped");
|
|
1461
|
+
} else {
|
|
1462
|
+
spinner.warn("Server was not running");
|
|
1132
1463
|
}
|
|
1133
1464
|
if (json) {
|
|
1134
|
-
formatOutput(
|
|
1465
|
+
formatOutput(result, true);
|
|
1135
1466
|
} else {
|
|
1136
|
-
formatSuccess("MCP
|
|
1467
|
+
formatSuccess("MCP server stopped.", false);
|
|
1137
1468
|
}
|
|
1138
1469
|
} catch (error) {
|
|
1139
1470
|
handleError(error, json);
|
|
@@ -1142,10 +1473,10 @@ var stopCommand = new Command11("stop").description("Stop and clean up the MCP s
|
|
|
1142
1473
|
});
|
|
1143
1474
|
|
|
1144
1475
|
// src/commands/mcp/test.ts
|
|
1145
|
-
import
|
|
1146
|
-
import { Command as
|
|
1147
|
-
import
|
|
1148
|
-
var testCommand = new
|
|
1476
|
+
import chalk10 from "chalk";
|
|
1477
|
+
import { Command as Command17 } from "commander";
|
|
1478
|
+
import ora14 from "ora";
|
|
1479
|
+
var testCommand = new Command17("test").description("Test MCP tools via the sandbox").argument("[tool]", "Tool name to test (lists tools if omitted)").argument("[args...]", "JSON arguments for the tool").option("--mcp-id <id>", "Specific MCP ID").action(
|
|
1149
1480
|
async (tool, args, options, command) => {
|
|
1150
1481
|
const globalOptions = command.optsWithGlobals();
|
|
1151
1482
|
const json = globalOptions.json ?? false;
|
|
@@ -1160,7 +1491,7 @@ var testCommand = new Command12("test").description("Test MCP tools via the sand
|
|
|
1160
1491
|
}
|
|
1161
1492
|
}
|
|
1162
1493
|
if (!tool) {
|
|
1163
|
-
const spinner =
|
|
1494
|
+
const spinner = ora14("Fetching available tools...").start();
|
|
1164
1495
|
const result = await api.post(
|
|
1165
1496
|
`/api/mcp/sandboxes/${mcpId}/test`,
|
|
1166
1497
|
{ action: "list" }
|
|
@@ -1173,7 +1504,7 @@ var testCommand = new Command12("test").description("Test MCP tools via the sand
|
|
|
1173
1504
|
if (tools.length === 0) {
|
|
1174
1505
|
console.log("No tools available.");
|
|
1175
1506
|
} else {
|
|
1176
|
-
console.log(
|
|
1507
|
+
console.log(chalk10.bold("\nAvailable Tools:\n"));
|
|
1177
1508
|
formatTable(
|
|
1178
1509
|
["Name", "Description"],
|
|
1179
1510
|
tools.map((t) => [t.name, t.description || "No description"]),
|
|
@@ -1196,7 +1527,7 @@ Test a tool: waniwani mcp test <tool-name> '{"arg": "value"}'`
|
|
|
1196
1527
|
);
|
|
1197
1528
|
}
|
|
1198
1529
|
}
|
|
1199
|
-
const spinner =
|
|
1530
|
+
const spinner = ora14(`Calling tool "${tool}"...`).start();
|
|
1200
1531
|
const startTime = Date.now();
|
|
1201
1532
|
const result = await api.post(
|
|
1202
1533
|
`/api/mcp/sandboxes/${mcpId}/test`,
|
|
@@ -1217,11 +1548,11 @@ Test a tool: waniwani mcp test <tool-name> '{"arg": "value"}'`
|
|
|
1217
1548
|
if (json) {
|
|
1218
1549
|
formatOutput(output, true);
|
|
1219
1550
|
} else {
|
|
1220
|
-
console.log(
|
|
1221
|
-
console.log(
|
|
1222
|
-
console.log(
|
|
1223
|
-
console.log(
|
|
1224
|
-
console.log(
|
|
1551
|
+
console.log(chalk10.bold("\nTool Result:\n"));
|
|
1552
|
+
console.log(chalk10.gray("Tool:"), tool);
|
|
1553
|
+
console.log(chalk10.gray("Input:"), JSON.stringify(toolArgs));
|
|
1554
|
+
console.log(chalk10.gray("Duration:"), `${duration}ms`);
|
|
1555
|
+
console.log(chalk10.gray("Result:"));
|
|
1225
1556
|
console.log(JSON.stringify(result.result, null, 2));
|
|
1226
1557
|
}
|
|
1227
1558
|
}
|
|
@@ -1233,13 +1564,13 @@ Test a tool: waniwani mcp test <tool-name> '{"arg": "value"}'`
|
|
|
1233
1564
|
);
|
|
1234
1565
|
|
|
1235
1566
|
// src/commands/mcp/use.ts
|
|
1236
|
-
import { Command as
|
|
1237
|
-
import
|
|
1238
|
-
var useCommand = new
|
|
1567
|
+
import { Command as Command18 } from "commander";
|
|
1568
|
+
import ora15 from "ora";
|
|
1569
|
+
var useCommand = new Command18("use").description("Select an MCP to use for subsequent commands").argument("<name>", "Name of the MCP to use").option("--global", "Save to global config instead of project config").action(async (name, options, command) => {
|
|
1239
1570
|
const globalOptions = command.optsWithGlobals();
|
|
1240
1571
|
const json = globalOptions.json ?? false;
|
|
1241
1572
|
try {
|
|
1242
|
-
const spinner =
|
|
1573
|
+
const spinner = ora15("Fetching MCPs...").start();
|
|
1243
1574
|
const mcps = await api.get("/api/admin/mcps");
|
|
1244
1575
|
spinner.stop();
|
|
1245
1576
|
const mcp = mcps.find((m) => m.name === name);
|
|
@@ -1274,78 +1605,21 @@ var useCommand = new Command13("use").description("Select an MCP to use for subs
|
|
|
1274
1605
|
}
|
|
1275
1606
|
});
|
|
1276
1607
|
|
|
1277
|
-
// src/commands/mcp/write-file.ts
|
|
1278
|
-
import { readFile as readFile3 } from "fs/promises";
|
|
1279
|
-
import { Command as Command14 } from "commander";
|
|
1280
|
-
import ora12 from "ora";
|
|
1281
|
-
var writeFileCommand = new Command14("write-file").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) => {
|
|
1282
|
-
const globalOptions = command.optsWithGlobals();
|
|
1283
|
-
const json = globalOptions.json ?? false;
|
|
1284
|
-
try {
|
|
1285
|
-
let mcpId = options.mcpId;
|
|
1286
|
-
if (!mcpId) {
|
|
1287
|
-
mcpId = await config.getMcpId();
|
|
1288
|
-
if (!mcpId) {
|
|
1289
|
-
throw new McpError(
|
|
1290
|
-
"No active MCP. Run 'waniwani mcp create <name>' or 'waniwani mcp use <name>'."
|
|
1291
|
-
);
|
|
1292
|
-
}
|
|
1293
|
-
}
|
|
1294
|
-
let content;
|
|
1295
|
-
let encoding = "utf8";
|
|
1296
|
-
if (options.content) {
|
|
1297
|
-
content = options.content;
|
|
1298
|
-
if (options.base64) {
|
|
1299
|
-
encoding = "base64";
|
|
1300
|
-
}
|
|
1301
|
-
} else if (options.file) {
|
|
1302
|
-
const fileBuffer = await readFile3(options.file);
|
|
1303
|
-
if (options.base64) {
|
|
1304
|
-
content = fileBuffer.toString("base64");
|
|
1305
|
-
encoding = "base64";
|
|
1306
|
-
} else {
|
|
1307
|
-
content = fileBuffer.toString("utf8");
|
|
1308
|
-
}
|
|
1309
|
-
} else {
|
|
1310
|
-
throw new CLIError(
|
|
1311
|
-
"Either --content or --file is required",
|
|
1312
|
-
"MISSING_CONTENT"
|
|
1313
|
-
);
|
|
1314
|
-
}
|
|
1315
|
-
const spinner = ora12(`Writing ${path}...`).start();
|
|
1316
|
-
const result = await api.post(
|
|
1317
|
-
`/api/mcp/sandboxes/${mcpId}/files`,
|
|
1318
|
-
{
|
|
1319
|
-
files: [{ path, content, encoding }]
|
|
1320
|
-
}
|
|
1321
|
-
);
|
|
1322
|
-
spinner.succeed(`Wrote ${path}`);
|
|
1323
|
-
if (json) {
|
|
1324
|
-
formatOutput(result, true);
|
|
1325
|
-
} else {
|
|
1326
|
-
formatSuccess(`File written: ${path}`, false);
|
|
1327
|
-
}
|
|
1328
|
-
} catch (error) {
|
|
1329
|
-
handleError(error, json);
|
|
1330
|
-
process.exit(1);
|
|
1331
|
-
}
|
|
1332
|
-
});
|
|
1333
|
-
|
|
1334
1608
|
// src/commands/mcp/index.ts
|
|
1335
|
-
var mcpCommand = new
|
|
1609
|
+
var mcpCommand = new Command19("mcp").description("MCP sandbox management commands").addCommand(createCommand).addCommand(listCommand2).addCommand(useCommand).addCommand(statusCommand).addCommand(startCommand).addCommand(stopCommand).addCommand(logsCommand).addCommand(deleteCommand).addCommand(testCommand).addCommand(deployCommand).addCommand(fileCommand).addCommand(runCommandCommand);
|
|
1336
1610
|
|
|
1337
1611
|
// src/commands/org/index.ts
|
|
1338
|
-
import { Command as
|
|
1612
|
+
import { Command as Command22 } from "commander";
|
|
1339
1613
|
|
|
1340
1614
|
// src/commands/org/list.ts
|
|
1341
|
-
import
|
|
1342
|
-
import { Command as
|
|
1343
|
-
import
|
|
1344
|
-
var
|
|
1615
|
+
import chalk11 from "chalk";
|
|
1616
|
+
import { Command as Command20 } from "commander";
|
|
1617
|
+
import ora16 from "ora";
|
|
1618
|
+
var listCommand3 = new Command20("list").description("List your organizations").action(async (_, command) => {
|
|
1345
1619
|
const globalOptions = command.optsWithGlobals();
|
|
1346
1620
|
const json = globalOptions.json ?? false;
|
|
1347
1621
|
try {
|
|
1348
|
-
const spinner =
|
|
1622
|
+
const spinner = ora16("Fetching organizations...").start();
|
|
1349
1623
|
const result = await api.get("/api/oauth/orgs");
|
|
1350
1624
|
spinner.stop();
|
|
1351
1625
|
const { orgs, activeOrgId } = result;
|
|
@@ -1365,11 +1639,11 @@ var listCommand2 = new Command16("list").description("List your organizations").
|
|
|
1365
1639
|
console.log("No organizations found.");
|
|
1366
1640
|
return;
|
|
1367
1641
|
}
|
|
1368
|
-
console.log(
|
|
1642
|
+
console.log(chalk11.bold("\nOrganizations:\n"));
|
|
1369
1643
|
const rows = orgs.map((o) => {
|
|
1370
1644
|
const isActive = o.id === activeOrgId;
|
|
1371
1645
|
return [
|
|
1372
|
-
isActive ?
|
|
1646
|
+
isActive ? chalk11.cyan(`* ${o.name}`) : ` ${o.name}`,
|
|
1373
1647
|
o.slug,
|
|
1374
1648
|
o.role
|
|
1375
1649
|
];
|
|
@@ -1379,7 +1653,7 @@ var listCommand2 = new Command16("list").description("List your organizations").
|
|
|
1379
1653
|
if (activeOrgId) {
|
|
1380
1654
|
const activeOrg = orgs.find((o) => o.id === activeOrgId);
|
|
1381
1655
|
if (activeOrg) {
|
|
1382
|
-
console.log(`Active organization: ${
|
|
1656
|
+
console.log(`Active organization: ${chalk11.cyan(activeOrg.name)}`);
|
|
1383
1657
|
}
|
|
1384
1658
|
}
|
|
1385
1659
|
console.log("\nSwitch organization: waniwani org switch <name>");
|
|
@@ -1391,13 +1665,13 @@ var listCommand2 = new Command16("list").description("List your organizations").
|
|
|
1391
1665
|
});
|
|
1392
1666
|
|
|
1393
1667
|
// src/commands/org/switch.ts
|
|
1394
|
-
import { Command as
|
|
1395
|
-
import
|
|
1396
|
-
var switchCommand = new
|
|
1668
|
+
import { Command as Command21 } from "commander";
|
|
1669
|
+
import ora17 from "ora";
|
|
1670
|
+
var switchCommand = new Command21("switch").description("Switch to a different organization").argument("<name>", "Name or slug of the organization to switch to").action(async (name, _, command) => {
|
|
1397
1671
|
const globalOptions = command.optsWithGlobals();
|
|
1398
1672
|
const json = globalOptions.json ?? false;
|
|
1399
1673
|
try {
|
|
1400
|
-
const spinner =
|
|
1674
|
+
const spinner = ora17("Fetching organizations...").start();
|
|
1401
1675
|
const { orgs } = await api.get("/api/oauth/orgs");
|
|
1402
1676
|
const org = orgs.find((o) => o.name === name || o.slug === name);
|
|
1403
1677
|
if (!org) {
|
|
@@ -1430,13 +1704,13 @@ var switchCommand = new Command17("switch").description("Switch to a different o
|
|
|
1430
1704
|
});
|
|
1431
1705
|
|
|
1432
1706
|
// src/commands/org/index.ts
|
|
1433
|
-
var orgCommand = new
|
|
1707
|
+
var orgCommand = new Command22("org").description("Organization management commands").addCommand(listCommand3).addCommand(switchCommand);
|
|
1434
1708
|
|
|
1435
1709
|
// src/commands/task.ts
|
|
1436
|
-
import
|
|
1437
|
-
import { Command as
|
|
1438
|
-
import
|
|
1439
|
-
var taskCommand = new
|
|
1710
|
+
import chalk12 from "chalk";
|
|
1711
|
+
import { Command as Command23 } from "commander";
|
|
1712
|
+
import ora18 from "ora";
|
|
1713
|
+
var taskCommand = new Command23("task").description("Send a task to Claude running in the sandbox").argument("<prompt>", "Task description/prompt").option("--mcp-id <id>", "Specific MCP ID").option("--model <model>", "Claude model to use").option("--max-steps <n>", "Maximum tool use steps").action(async (prompt, options, command) => {
|
|
1440
1714
|
const globalOptions = command.optsWithGlobals();
|
|
1441
1715
|
const json = globalOptions.json ?? false;
|
|
1442
1716
|
try {
|
|
@@ -1460,10 +1734,10 @@ var taskCommand = new Command19("task").description("Send a task to Claude runni
|
|
|
1460
1734
|
const maxSteps = options.maxSteps ? Number.parseInt(options.maxSteps, 10) : defaults.maxSteps;
|
|
1461
1735
|
if (!json) {
|
|
1462
1736
|
console.log();
|
|
1463
|
-
console.log(
|
|
1737
|
+
console.log(chalk12.bold("Task:"), prompt);
|
|
1464
1738
|
console.log();
|
|
1465
1739
|
}
|
|
1466
|
-
const spinner =
|
|
1740
|
+
const spinner = ora18("Starting task...").start();
|
|
1467
1741
|
const baseUrl = await api.getBaseUrl();
|
|
1468
1742
|
const response = await fetch(
|
|
1469
1743
|
`${baseUrl}/api/mcp/sandboxes/${mcpId}/task`,
|
|
@@ -1517,7 +1791,7 @@ var taskCommand = new Command19("task").description("Send a task to Claude runni
|
|
|
1517
1791
|
const event = parsed;
|
|
1518
1792
|
steps.push({ type: "text", text: event.content });
|
|
1519
1793
|
if (!json && event.content) {
|
|
1520
|
-
console.log(
|
|
1794
|
+
console.log(chalk12.white(event.content));
|
|
1521
1795
|
}
|
|
1522
1796
|
} else if (parsed.type === "tool_call") {
|
|
1523
1797
|
const event = parsed;
|
|
@@ -1528,24 +1802,24 @@ var taskCommand = new Command19("task").description("Send a task to Claude runni
|
|
|
1528
1802
|
output: event.output
|
|
1529
1803
|
});
|
|
1530
1804
|
if (!json) {
|
|
1531
|
-
console.log(
|
|
1805
|
+
console.log(chalk12.cyan(`> Using tool: ${event.tool}`));
|
|
1532
1806
|
if (event.input?.command) {
|
|
1533
|
-
console.log(
|
|
1807
|
+
console.log(chalk12.gray(` $ ${event.input.command}`));
|
|
1534
1808
|
}
|
|
1535
1809
|
if (event.output) {
|
|
1536
1810
|
const outputLines = event.output.split("\n");
|
|
1537
1811
|
if (outputLines.length > 10) {
|
|
1538
1812
|
console.log(
|
|
1539
|
-
|
|
1813
|
+
chalk12.gray(outputLines.slice(0, 5).join("\n"))
|
|
1540
1814
|
);
|
|
1541
1815
|
console.log(
|
|
1542
|
-
|
|
1816
|
+
chalk12.gray(
|
|
1543
1817
|
` ... (${outputLines.length - 10} more lines)`
|
|
1544
1818
|
)
|
|
1545
1819
|
);
|
|
1546
|
-
console.log(
|
|
1820
|
+
console.log(chalk12.gray(outputLines.slice(-5).join("\n")));
|
|
1547
1821
|
} else {
|
|
1548
|
-
console.log(
|
|
1822
|
+
console.log(chalk12.gray(event.output));
|
|
1549
1823
|
}
|
|
1550
1824
|
}
|
|
1551
1825
|
console.log();
|
|
@@ -1572,12 +1846,12 @@ var taskCommand = new Command19("task").description("Send a task to Claude runni
|
|
|
1572
1846
|
} else {
|
|
1573
1847
|
console.log();
|
|
1574
1848
|
console.log(
|
|
1575
|
-
|
|
1849
|
+
chalk12.green("\u2713"),
|
|
1576
1850
|
`Task completed in ${finalStepCount} steps.`
|
|
1577
1851
|
);
|
|
1578
1852
|
if (maxStepsReached) {
|
|
1579
1853
|
console.log(
|
|
1580
|
-
|
|
1854
|
+
chalk12.yellow("\u26A0"),
|
|
1581
1855
|
"Maximum steps reached. Task may be incomplete."
|
|
1582
1856
|
);
|
|
1583
1857
|
}
|
|
@@ -1590,7 +1864,7 @@ var taskCommand = new Command19("task").description("Send a task to Claude runni
|
|
|
1590
1864
|
|
|
1591
1865
|
// src/cli.ts
|
|
1592
1866
|
var version = "0.1.0";
|
|
1593
|
-
var program = new
|
|
1867
|
+
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");
|
|
1594
1868
|
program.addCommand(loginCommand);
|
|
1595
1869
|
program.addCommand(logoutCommand);
|
|
1596
1870
|
program.addCommand(initCommand);
|