wattetheria 0.4.0 → 0.4.2
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/.env.release +1 -1
- package/README.md +244 -994
- package/lib/cli.js +169 -2
- package/package.json +1 -1
package/lib/cli.js
CHANGED
|
@@ -37,6 +37,7 @@ const NATIVE_ARCH_ALIASES = new Map([
|
|
|
37
37
|
]);
|
|
38
38
|
const BANNER_COMMANDS = new Set([
|
|
39
39
|
"help",
|
|
40
|
+
"setup",
|
|
40
41
|
"install",
|
|
41
42
|
"start",
|
|
42
43
|
"up",
|
|
@@ -55,11 +56,13 @@ function printHelp() {
|
|
|
55
56
|
|
|
56
57
|
Usage:
|
|
57
58
|
npx wattetheria [command] [options]
|
|
59
|
+
npx wattetheria setup
|
|
58
60
|
npx wattetheria install
|
|
59
61
|
|
|
60
62
|
Commands:
|
|
61
63
|
version Show Wattetheria release version
|
|
62
64
|
images Show configured release images
|
|
65
|
+
setup Install the local stack and finish first-time runtime/MCP setup
|
|
63
66
|
install Prepare deployment, pull images, and start the stack
|
|
64
67
|
start Start an existing deployment
|
|
65
68
|
status Show docker compose status
|
|
@@ -952,6 +955,29 @@ function runCompose(options, args, capture = false) {
|
|
|
952
955
|
return result;
|
|
953
956
|
}
|
|
954
957
|
|
|
958
|
+
const RELEASE_SERVICES = [
|
|
959
|
+
"kernel",
|
|
960
|
+
"wattswarm-postgres",
|
|
961
|
+
"wattswarm-runtime",
|
|
962
|
+
"wattswarm-kernel",
|
|
963
|
+
"wattswarm-worker"
|
|
964
|
+
];
|
|
965
|
+
|
|
966
|
+
function runningComposeServices(options) {
|
|
967
|
+
const result = runCompose(options, ["ps", "--status", "running", "--services"], true);
|
|
968
|
+
return new Set(
|
|
969
|
+
(result.stdout || "")
|
|
970
|
+
.split(/\r?\n/)
|
|
971
|
+
.map((line) => line.trim())
|
|
972
|
+
.filter(Boolean)
|
|
973
|
+
);
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
function composeStackIsRunning(options) {
|
|
977
|
+
const runningServices = runningComposeServices(options);
|
|
978
|
+
return RELEASE_SERVICES.every((service) => runningServices.has(service));
|
|
979
|
+
}
|
|
980
|
+
|
|
955
981
|
async function waitForHttp(name, url, maxAttempts = 60, delayMs = 2000) {
|
|
956
982
|
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
957
983
|
try {
|
|
@@ -1025,8 +1051,69 @@ function printSummary(options) {
|
|
|
1025
1051
|
console.log(`Deploy dir: ${options.dir}`);
|
|
1026
1052
|
}
|
|
1027
1053
|
|
|
1028
|
-
|
|
1029
|
-
|
|
1054
|
+
function supervisionUrl(options) {
|
|
1055
|
+
const envMap = readEnvFile(envFilePath(options));
|
|
1056
|
+
const kernelHost = getEnvValue(envMap, "WATTETHERIA_CONTROL_PLANE_BIND_HOST", "127.0.0.1");
|
|
1057
|
+
const kernelPort = getEnvValue(envMap, "WATTETHERIA_CONTROL_PLANE_PORT", "7777");
|
|
1058
|
+
return `http://${kernelHost}:${kernelPort}/supervision`;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
function mcpServerConfigSnippet(options) {
|
|
1062
|
+
const args = ["wattetheria", "mcp-proxy"];
|
|
1063
|
+
if (path.resolve(options.dir) !== path.resolve(DEFAULT_DEPLOY_DIR)) {
|
|
1064
|
+
args.push("--dir", options.dir);
|
|
1065
|
+
}
|
|
1066
|
+
return JSON.stringify({
|
|
1067
|
+
mcpServers: {
|
|
1068
|
+
wattetheria: {
|
|
1069
|
+
command: "npx",
|
|
1070
|
+
args
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
}, null, 2);
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
function printSetupHint() {
|
|
1077
|
+
console.log("");
|
|
1078
|
+
console.log("To finish first-time setup, run:");
|
|
1079
|
+
console.log(" npx wattetheria setup");
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
function printManualSetupChecklist(options) {
|
|
1083
|
+
console.log("");
|
|
1084
|
+
console.log("Finish setup:");
|
|
1085
|
+
console.log("1. Open Supervision and configure the runtime:");
|
|
1086
|
+
console.log(` ${supervisionUrl(options)}`);
|
|
1087
|
+
console.log("");
|
|
1088
|
+
console.log("2. Add Wattetheria MCP to your agent runtime:");
|
|
1089
|
+
console.log(mcpServerConfigSnippet(options));
|
|
1090
|
+
console.log("");
|
|
1091
|
+
console.log("3. Restart Wattetheria so runtime config takes effect:");
|
|
1092
|
+
console.log(" npx wattetheria restart");
|
|
1093
|
+
console.log("");
|
|
1094
|
+
console.log("4. Restart your agent runtime so MCP config takes effect.");
|
|
1095
|
+
console.log("");
|
|
1096
|
+
console.log("5. Verify MCP access from the agent runtime:");
|
|
1097
|
+
console.log(" - list Wattetheria MCP tools");
|
|
1098
|
+
console.log(" - call one read-only Wattetheria MCP tool");
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
async function waitForEnter(message) {
|
|
1102
|
+
const rl = createInterface({
|
|
1103
|
+
input: process.stdin,
|
|
1104
|
+
output: process.stdout
|
|
1105
|
+
});
|
|
1106
|
+
try {
|
|
1107
|
+
await rl.question(message);
|
|
1108
|
+
} finally {
|
|
1109
|
+
rl.close();
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
async function install(options, behavior = {}) {
|
|
1114
|
+
if (!behavior.dockerAlreadyChecked) {
|
|
1115
|
+
await ensureDockerAvailable({ interactive: true });
|
|
1116
|
+
}
|
|
1030
1117
|
ensureDeploymentAssets(options);
|
|
1031
1118
|
if (options.tag) {
|
|
1032
1119
|
console.log(`Pinning release images to requested tag ${options.tag}.`);
|
|
@@ -1042,6 +1129,83 @@ async function install(options) {
|
|
|
1042
1129
|
await runHealthChecks(options);
|
|
1043
1130
|
}
|
|
1044
1131
|
printSummary(options);
|
|
1132
|
+
if (!behavior.suppressSetupHint) {
|
|
1133
|
+
printSetupHint();
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
async function setup(options) {
|
|
1138
|
+
console.log("Checking Docker runtime...");
|
|
1139
|
+
const dockerStatus = getDockerStatus();
|
|
1140
|
+
if (!dockerStatus.ready) {
|
|
1141
|
+
throw new Error([
|
|
1142
|
+
formatDockerStatusMessage(dockerStatus),
|
|
1143
|
+
"",
|
|
1144
|
+
"Install Docker, start it, then rerun:",
|
|
1145
|
+
" npx wattetheria setup"
|
|
1146
|
+
].join("\n"));
|
|
1147
|
+
}
|
|
1148
|
+
console.log("[ok] Docker runtime is ready.");
|
|
1149
|
+
|
|
1150
|
+
const deployment = deploymentState(options.dir);
|
|
1151
|
+
console.log("");
|
|
1152
|
+
if (deployment.runnable) {
|
|
1153
|
+
console.log("[1/6] Start existing Wattetheria deployment");
|
|
1154
|
+
if (composeStackIsRunning(options)) {
|
|
1155
|
+
console.log("Deployment already initialized and running. Skipping docker compose up.");
|
|
1156
|
+
if (options.healthChecks) {
|
|
1157
|
+
await runHealthChecks(options);
|
|
1158
|
+
}
|
|
1159
|
+
printSummary(options);
|
|
1160
|
+
} else {
|
|
1161
|
+
console.log("Deployment already initialized. Starting existing stack...");
|
|
1162
|
+
await start(options);
|
|
1163
|
+
}
|
|
1164
|
+
} else {
|
|
1165
|
+
console.log("[1/6] Install Wattetheria");
|
|
1166
|
+
await install(options, {
|
|
1167
|
+
dockerAlreadyChecked: true,
|
|
1168
|
+
suppressSetupHint: true
|
|
1169
|
+
});
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
if (!isInteractiveTerminal()) {
|
|
1173
|
+
printManualSetupChecklist(options);
|
|
1174
|
+
return;
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
const url = supervisionUrl(options);
|
|
1178
|
+
console.log("");
|
|
1179
|
+
console.log("[2/6] Configure runtime");
|
|
1180
|
+
console.log(`Open: ${url}`);
|
|
1181
|
+
const opened = openUrl(url);
|
|
1182
|
+
if (!opened) {
|
|
1183
|
+
console.log("Open the URL above in your browser.");
|
|
1184
|
+
}
|
|
1185
|
+
await waitForEnter("After saving runtime config, press Enter to continue.");
|
|
1186
|
+
|
|
1187
|
+
console.log("");
|
|
1188
|
+
console.log("[3/6] Install MCP in your agent runtime");
|
|
1189
|
+
console.log(mcpServerConfigSnippet(options));
|
|
1190
|
+
await waitForEnter("After saving MCP config, press Enter to continue.");
|
|
1191
|
+
|
|
1192
|
+
console.log("");
|
|
1193
|
+
console.log("[4/6] Restart Wattetheria");
|
|
1194
|
+
await restart(options);
|
|
1195
|
+
|
|
1196
|
+
console.log("");
|
|
1197
|
+
console.log("[5/6] Restart your agent runtime");
|
|
1198
|
+
await waitForEnter("After restarting your agent runtime, press Enter to continue.");
|
|
1199
|
+
|
|
1200
|
+
console.log("");
|
|
1201
|
+
console.log("[6/6] Verify MCP access");
|
|
1202
|
+
console.log("From the agent runtime:");
|
|
1203
|
+
console.log("- list Wattetheria MCP tools");
|
|
1204
|
+
console.log("- call one read-only Wattetheria MCP tool");
|
|
1205
|
+
await waitForEnter("After verifying MCP access, press Enter to finish.");
|
|
1206
|
+
|
|
1207
|
+
console.log("");
|
|
1208
|
+
console.log("Setup complete.");
|
|
1045
1209
|
}
|
|
1046
1210
|
|
|
1047
1211
|
async function start(options) {
|
|
@@ -1681,6 +1845,9 @@ async function run(argv) {
|
|
|
1681
1845
|
case "images":
|
|
1682
1846
|
printImages(options);
|
|
1683
1847
|
return;
|
|
1848
|
+
case "setup":
|
|
1849
|
+
await setup(options);
|
|
1850
|
+
return;
|
|
1684
1851
|
case "install":
|
|
1685
1852
|
await install(options);
|
|
1686
1853
|
return;
|