@schuttdev/gigai 0.1.0-beta.14 → 0.1.0-beta.16
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/{dist-EG3MXFDE.js → dist-GANOIL6Z.js} +196 -18
- package/dist/index.js +81 -25
- package/package.json +1 -1
|
@@ -45,11 +45,16 @@ import { spawn as spawn4 } from "child_process";
|
|
|
45
45
|
import { input, select, checkbox, confirm } from "@inquirer/prompts";
|
|
46
46
|
import { writeFile as writeFile2 } from "fs/promises";
|
|
47
47
|
import { resolve as resolve4 } from "path";
|
|
48
|
-
import { execFile } from "child_process";
|
|
48
|
+
import { execFile, spawn as spawn5 } from "child_process";
|
|
49
49
|
import { promisify } from "util";
|
|
50
50
|
import { input as input2 } from "@inquirer/prompts";
|
|
51
51
|
import { readFile as readFile4, writeFile as writeFile3 } from "fs/promises";
|
|
52
52
|
import { resolve as resolve5 } from "path";
|
|
53
|
+
import { writeFile as writeFile4 } from "fs/promises";
|
|
54
|
+
import { resolve as resolve6, join as join3 } from "path";
|
|
55
|
+
import { homedir, platform } from "os";
|
|
56
|
+
import { execFile as execFile2 } from "child_process";
|
|
57
|
+
import { promisify as promisify2 } from "util";
|
|
53
58
|
function connectWithToken(store, encryptedToken, orgUuid, encryptionKey, sessionTtlSeconds) {
|
|
54
59
|
let payload;
|
|
55
60
|
try {
|
|
@@ -267,7 +272,7 @@ function executeTool(entry, args, timeout) {
|
|
|
267
272
|
`Cannot execute tool of type: ${entry.type}`
|
|
268
273
|
);
|
|
269
274
|
}
|
|
270
|
-
return new Promise((
|
|
275
|
+
return new Promise((resolve7, reject) => {
|
|
271
276
|
const start = Date.now();
|
|
272
277
|
const stdoutChunks = [];
|
|
273
278
|
const stderrChunks = [];
|
|
@@ -315,7 +320,7 @@ function executeTool(entry, args, timeout) {
|
|
|
315
320
|
reject(new GigaiError(ErrorCode.EXEC_TIMEOUT, `Tool execution timed out after ${effectiveTimeout}ms`));
|
|
316
321
|
return;
|
|
317
322
|
}
|
|
318
|
-
|
|
323
|
+
resolve7({
|
|
319
324
|
stdout: Buffer.concat(stdoutChunks).toString("utf8"),
|
|
320
325
|
stderr: Buffer.concat(stderrChunks).toString("utf8"),
|
|
321
326
|
exitCode: exitCode ?? 1,
|
|
@@ -607,7 +612,7 @@ async function execCommandSafe(command, args, config) {
|
|
|
607
612
|
throw new GigaiError(ErrorCode.VALIDATION_ERROR, "Null byte in argument");
|
|
608
613
|
}
|
|
609
614
|
}
|
|
610
|
-
return new Promise((
|
|
615
|
+
return new Promise((resolve7, reject) => {
|
|
611
616
|
const child = spawn2(command, args, {
|
|
612
617
|
shell: false,
|
|
613
618
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -629,7 +634,7 @@ async function execCommandSafe(command, args, config) {
|
|
|
629
634
|
reject(new GigaiError(ErrorCode.EXEC_FAILED, `Failed to spawn ${command}: ${err.message}`));
|
|
630
635
|
});
|
|
631
636
|
child.on("close", (exitCode) => {
|
|
632
|
-
|
|
637
|
+
resolve7({
|
|
633
638
|
stdout: Buffer.concat(stdoutChunks).toString("utf8"),
|
|
634
639
|
stderr: Buffer.concat(stderrChunks).toString("utf8"),
|
|
635
640
|
exitCode: exitCode ?? 1
|
|
@@ -833,13 +838,13 @@ async function loadConfig(path) {
|
|
|
833
838
|
return GigaiConfigSchema.parse(json);
|
|
834
839
|
}
|
|
835
840
|
function runCommand(command, args) {
|
|
836
|
-
return new Promise((
|
|
841
|
+
return new Promise((resolve7, reject) => {
|
|
837
842
|
const child = spawn3(command, args, { shell: false, stdio: ["ignore", "pipe", "pipe"] });
|
|
838
843
|
const chunks = [];
|
|
839
844
|
child.stdout.on("data", (chunk) => chunks.push(chunk));
|
|
840
845
|
child.on("error", reject);
|
|
841
846
|
child.on("close", (exitCode) => {
|
|
842
|
-
|
|
847
|
+
resolve7({ stdout: Buffer.concat(chunks).toString("utf8").trim(), exitCode: exitCode ?? 1 });
|
|
843
848
|
});
|
|
844
849
|
});
|
|
845
850
|
}
|
|
@@ -901,6 +906,41 @@ async function getTailscaleDnsName() {
|
|
|
901
906
|
return null;
|
|
902
907
|
}
|
|
903
908
|
}
|
|
909
|
+
async function ensureTailscaleFunnel(port) {
|
|
910
|
+
const dnsName = await getTailscaleDnsName();
|
|
911
|
+
if (!dnsName) {
|
|
912
|
+
throw new Error("Tailscale is not running or not connected. Install/start Tailscale first.");
|
|
913
|
+
}
|
|
914
|
+
console.log(" Enabling Tailscale Funnel...");
|
|
915
|
+
try {
|
|
916
|
+
const { stdout, stderr } = await execFileAsync("tailscale", ["funnel", "--bg", `${port}`]);
|
|
917
|
+
const output = stdout + stderr;
|
|
918
|
+
if (output.includes("Funnel is not enabled")) {
|
|
919
|
+
const urlMatch = output.match(/(https:\/\/login\.tailscale\.com\/\S+)/);
|
|
920
|
+
const enableUrl = urlMatch?.[1] ?? "https://login.tailscale.com/admin/machines";
|
|
921
|
+
console.log(`
|
|
922
|
+
Funnel is not enabled on your tailnet.`);
|
|
923
|
+
console.log(` Enable it here: ${enableUrl}
|
|
924
|
+
`);
|
|
925
|
+
await confirm({ message: "I've enabled Funnel in my Tailscale admin. Continue?", default: true });
|
|
926
|
+
const retry = await execFileAsync("tailscale", ["funnel", "--bg", `${port}`]);
|
|
927
|
+
if ((retry.stdout + retry.stderr).includes("Funnel is not enabled")) {
|
|
928
|
+
throw new Error("Funnel is still not enabled. Please enable it in your Tailscale admin and try again.");
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
} catch (e) {
|
|
932
|
+
if (e.message.includes("Funnel is still not enabled")) throw e;
|
|
933
|
+
}
|
|
934
|
+
try {
|
|
935
|
+
const { stdout } = await execFileAsync("tailscale", ["funnel", "status"]);
|
|
936
|
+
if (stdout.includes("No serve config")) {
|
|
937
|
+
throw new Error("Funnel setup failed. Run 'tailscale funnel --bg " + port + "' manually to debug.");
|
|
938
|
+
}
|
|
939
|
+
} catch {
|
|
940
|
+
}
|
|
941
|
+
console.log(` Tailscale Funnel active: https://${dnsName}`);
|
|
942
|
+
return `https://${dnsName}`;
|
|
943
|
+
}
|
|
904
944
|
async function runInit() {
|
|
905
945
|
console.log("\n gigai server setup\n");
|
|
906
946
|
const httpsProvider = await select({
|
|
@@ -919,7 +959,6 @@ async function runInit() {
|
|
|
919
959
|
provider: "tailscale",
|
|
920
960
|
funnelPort: 7443
|
|
921
961
|
};
|
|
922
|
-
console.log(" Will use Tailscale Funnel for HTTPS.");
|
|
923
962
|
break;
|
|
924
963
|
case "cloudflare": {
|
|
925
964
|
const tunnelName = await input({
|
|
@@ -1023,10 +1062,11 @@ async function runInit() {
|
|
|
1023
1062
|
Config written to: ${configPath}`);
|
|
1024
1063
|
let serverUrl;
|
|
1025
1064
|
if (httpsProvider === "tailscale") {
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
console.
|
|
1065
|
+
try {
|
|
1066
|
+
serverUrl = await ensureTailscaleFunnel(port);
|
|
1067
|
+
} catch (e) {
|
|
1068
|
+
console.error(` ${e.message}`);
|
|
1069
|
+
console.log(" You can enable Funnel later and run 'gigai server start' manually.\n");
|
|
1030
1070
|
}
|
|
1031
1071
|
} else if (httpsProvider === "cloudflare" && httpsConfig && "domain" in httpsConfig && httpsConfig.domain) {
|
|
1032
1072
|
serverUrl = `https://${httpsConfig.domain}`;
|
|
@@ -1038,16 +1078,29 @@ async function runInit() {
|
|
|
1038
1078
|
required: true
|
|
1039
1079
|
});
|
|
1040
1080
|
}
|
|
1081
|
+
console.log("\n Starting server...");
|
|
1082
|
+
const serverArgs = ["server", "start", "--config", configPath];
|
|
1083
|
+
if (!httpsConfig) serverArgs.push("--dev");
|
|
1084
|
+
const child = spawn5("gigai", serverArgs, {
|
|
1085
|
+
detached: true,
|
|
1086
|
+
stdio: "ignore",
|
|
1087
|
+
cwd: resolve4(".")
|
|
1088
|
+
});
|
|
1089
|
+
child.unref();
|
|
1090
|
+
await new Promise((r) => setTimeout(r, 1500));
|
|
1091
|
+
try {
|
|
1092
|
+
const res = await fetch(`http://localhost:${port}/health`);
|
|
1093
|
+
if (res.ok) {
|
|
1094
|
+
console.log(` Server running on port ${port} (PID ${child.pid})`);
|
|
1095
|
+
}
|
|
1096
|
+
} catch {
|
|
1097
|
+
console.log(` Server starting in background (PID ${child.pid})`);
|
|
1098
|
+
}
|
|
1041
1099
|
const store = new AuthStore();
|
|
1042
1100
|
const code = generatePairingCode(store, config.auth.pairingTtlSeconds);
|
|
1043
1101
|
store.destroy();
|
|
1044
1102
|
console.log(`
|
|
1045
|
-
|
|
1046
|
-
console.log(` Expires in ${config.auth.pairingTtlSeconds / 60} minutes.
|
|
1047
|
-
`);
|
|
1048
|
-
console.log(` Start the server with: gigai server start${httpsConfig ? "" : " --dev"}
|
|
1049
|
-
`);
|
|
1050
|
-
console.log(` Then paste this into Claude to pair:
|
|
1103
|
+
Paste this into Claude to pair:
|
|
1051
1104
|
`);
|
|
1052
1105
|
console.log(` \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`);
|
|
1053
1106
|
console.log(` Install the gigai CLI and pair with my server:
|
|
@@ -1059,6 +1112,10 @@ async function runInit() {
|
|
|
1059
1112
|
`);
|
|
1060
1113
|
console.log(` Then show me the skill file output so I can save it.`);
|
|
1061
1114
|
console.log(` \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`);
|
|
1115
|
+
console.log(`
|
|
1116
|
+
Pairing code expires in ${config.auth.pairingTtlSeconds / 60} minutes.`);
|
|
1117
|
+
console.log(` Run 'gigai server pair' to generate a new one.
|
|
1118
|
+
`);
|
|
1062
1119
|
}
|
|
1063
1120
|
async function loadConfigFile(path) {
|
|
1064
1121
|
const configPath = resolve5(path ?? "gigai.config.json");
|
|
@@ -1183,6 +1240,125 @@ Note: The server must be running for the client to use this code.`);
|
|
|
1183
1240
|
console.log(`For a live pairing code, use the server's /auth/pair/generate endpoint.`);
|
|
1184
1241
|
store.destroy();
|
|
1185
1242
|
}
|
|
1243
|
+
var execFileAsync2 = promisify2(execFile2);
|
|
1244
|
+
function getGigaiBin() {
|
|
1245
|
+
return process.argv[1] ?? "gigai";
|
|
1246
|
+
}
|
|
1247
|
+
function getLaunchdPlist(configPath) {
|
|
1248
|
+
const bin = getGigaiBin();
|
|
1249
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
1250
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
1251
|
+
<plist version="1.0">
|
|
1252
|
+
<dict>
|
|
1253
|
+
<key>Label</key>
|
|
1254
|
+
<string>com.gigai.server</string>
|
|
1255
|
+
<key>ProgramArguments</key>
|
|
1256
|
+
<array>
|
|
1257
|
+
<string>${bin}</string>
|
|
1258
|
+
<string>server</string>
|
|
1259
|
+
<string>start</string>
|
|
1260
|
+
<string>--config</string>
|
|
1261
|
+
<string>${configPath}</string>
|
|
1262
|
+
</array>
|
|
1263
|
+
<key>RunAtLoad</key>
|
|
1264
|
+
<true/>
|
|
1265
|
+
<key>KeepAlive</key>
|
|
1266
|
+
<true/>
|
|
1267
|
+
<key>StandardOutPath</key>
|
|
1268
|
+
<string>${join3(homedir(), ".gigai", "server.log")}</string>
|
|
1269
|
+
<key>StandardErrorPath</key>
|
|
1270
|
+
<string>${join3(homedir(), ".gigai", "server.log")}</string>
|
|
1271
|
+
<key>WorkingDirectory</key>
|
|
1272
|
+
<string>${homedir()}</string>
|
|
1273
|
+
</dict>
|
|
1274
|
+
</plist>
|
|
1275
|
+
`;
|
|
1276
|
+
}
|
|
1277
|
+
function getSystemdUnit(configPath) {
|
|
1278
|
+
const bin = getGigaiBin();
|
|
1279
|
+
return `[Unit]
|
|
1280
|
+
Description=gigai server
|
|
1281
|
+
After=network.target
|
|
1282
|
+
|
|
1283
|
+
[Service]
|
|
1284
|
+
Type=simple
|
|
1285
|
+
ExecStart=${bin} server start --config ${configPath}
|
|
1286
|
+
Restart=always
|
|
1287
|
+
RestartSec=5
|
|
1288
|
+
WorkingDirectory=${homedir()}
|
|
1289
|
+
|
|
1290
|
+
[Install]
|
|
1291
|
+
WantedBy=default.target
|
|
1292
|
+
`;
|
|
1293
|
+
}
|
|
1294
|
+
async function installDaemon(configPath) {
|
|
1295
|
+
const config = resolve6(configPath ?? "gigai.config.json");
|
|
1296
|
+
const os = platform();
|
|
1297
|
+
if (os === "darwin") {
|
|
1298
|
+
const plistPath = join3(homedir(), "Library", "LaunchAgents", "com.gigai.server.plist");
|
|
1299
|
+
await writeFile4(plistPath, getLaunchdPlist(config));
|
|
1300
|
+
console.log(` Wrote launchd plist: ${plistPath}`);
|
|
1301
|
+
try {
|
|
1302
|
+
await execFileAsync2("launchctl", ["load", plistPath]);
|
|
1303
|
+
console.log(" Service loaded and started.");
|
|
1304
|
+
} catch {
|
|
1305
|
+
console.log(` Load it with: launchctl load ${plistPath}`);
|
|
1306
|
+
}
|
|
1307
|
+
console.log(` Logs: ~/.gigai/server.log`);
|
|
1308
|
+
console.log(` Stop: launchctl unload ${plistPath}`);
|
|
1309
|
+
} else if (os === "linux") {
|
|
1310
|
+
const unitDir = join3(homedir(), ".config", "systemd", "user");
|
|
1311
|
+
const unitPath = join3(unitDir, "gigai.service");
|
|
1312
|
+
const { mkdir: mkdir2 } = await import("fs/promises");
|
|
1313
|
+
await mkdir2(unitDir, { recursive: true });
|
|
1314
|
+
await writeFile4(unitPath, getSystemdUnit(config));
|
|
1315
|
+
console.log(` Wrote systemd unit: ${unitPath}`);
|
|
1316
|
+
try {
|
|
1317
|
+
await execFileAsync2("systemctl", ["--user", "daemon-reload"]);
|
|
1318
|
+
await execFileAsync2("systemctl", ["--user", "enable", "--now", "gigai"]);
|
|
1319
|
+
console.log(" Service enabled and started.");
|
|
1320
|
+
} catch {
|
|
1321
|
+
console.log(" Enable it with: systemctl --user enable --now gigai");
|
|
1322
|
+
}
|
|
1323
|
+
console.log(` Logs: journalctl --user -u gigai -f`);
|
|
1324
|
+
console.log(` Stop: systemctl --user stop gigai`);
|
|
1325
|
+
console.log(` Remove: systemctl --user disable gigai`);
|
|
1326
|
+
} else {
|
|
1327
|
+
console.log(" Persistent daemon not supported on this platform.");
|
|
1328
|
+
console.log(" Run 'gigai server start' manually.");
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
async function uninstallDaemon() {
|
|
1332
|
+
const os = platform();
|
|
1333
|
+
if (os === "darwin") {
|
|
1334
|
+
const plistPath = join3(homedir(), "Library", "LaunchAgents", "com.gigai.server.plist");
|
|
1335
|
+
try {
|
|
1336
|
+
await execFileAsync2("launchctl", ["unload", plistPath]);
|
|
1337
|
+
} catch {
|
|
1338
|
+
}
|
|
1339
|
+
const { unlink: unlink2 } = await import("fs/promises");
|
|
1340
|
+
try {
|
|
1341
|
+
await unlink2(plistPath);
|
|
1342
|
+
console.log(" Service removed.");
|
|
1343
|
+
} catch {
|
|
1344
|
+
console.log(" No service found.");
|
|
1345
|
+
}
|
|
1346
|
+
} else if (os === "linux") {
|
|
1347
|
+
try {
|
|
1348
|
+
await execFileAsync2("systemctl", ["--user", "disable", "--now", "gigai"]);
|
|
1349
|
+
} catch {
|
|
1350
|
+
}
|
|
1351
|
+
const unitPath = join3(homedir(), ".config", "systemd", "user", "gigai.service");
|
|
1352
|
+
const { unlink: unlink2 } = await import("fs/promises");
|
|
1353
|
+
try {
|
|
1354
|
+
await unlink2(unitPath);
|
|
1355
|
+
await execFileAsync2("systemctl", ["--user", "daemon-reload"]);
|
|
1356
|
+
console.log(" Service removed.");
|
|
1357
|
+
} catch {
|
|
1358
|
+
console.log(" No service found.");
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1186
1362
|
async function startServer() {
|
|
1187
1363
|
const { values } = parseArgs({
|
|
1188
1364
|
options: {
|
|
@@ -1238,9 +1414,11 @@ async function startServer() {
|
|
|
1238
1414
|
export {
|
|
1239
1415
|
createServer,
|
|
1240
1416
|
generateServerPairingCode,
|
|
1417
|
+
installDaemon,
|
|
1241
1418
|
loadConfig,
|
|
1242
1419
|
runInit,
|
|
1243
1420
|
startServer,
|
|
1421
|
+
uninstallDaemon,
|
|
1244
1422
|
unwrapTool,
|
|
1245
1423
|
wrapCli,
|
|
1246
1424
|
wrapImport,
|
package/dist/index.js
CHANGED
|
@@ -51,8 +51,8 @@ function getOrgUUID() {
|
|
|
51
51
|
if (process.env.GIGAI_ORG_UUID) {
|
|
52
52
|
return process.env.GIGAI_ORG_UUID;
|
|
53
53
|
}
|
|
54
|
-
const proxyUrl = process.env.
|
|
55
|
-
const jwtMatch = proxyUrl.match(
|
|
54
|
+
const proxyUrl = process.env.HTTPS_PROXY || process.env.HTTP_PROXY || "";
|
|
55
|
+
const jwtMatch = proxyUrl.match(/jwt_([^@]+)/);
|
|
56
56
|
if (jwtMatch) {
|
|
57
57
|
try {
|
|
58
58
|
const payload = decodeJWTPayload(jwtMatch[1]);
|
|
@@ -62,18 +62,25 @@ function getOrgUUID() {
|
|
|
62
62
|
} catch {
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
|
+
const anthropicProxy = process.env.ANTHROPIC_PROXY_URL ?? "";
|
|
66
|
+
const anthropicJwtMatch = anthropicProxy.match(/([A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+)/);
|
|
67
|
+
if (anthropicJwtMatch) {
|
|
68
|
+
try {
|
|
69
|
+
const payload = decodeJWTPayload(anthropicJwtMatch[1]);
|
|
70
|
+
if (payload.organization_uuid) {
|
|
71
|
+
return payload.organization_uuid;
|
|
72
|
+
}
|
|
73
|
+
} catch {
|
|
74
|
+
}
|
|
75
|
+
}
|
|
65
76
|
const apiKey = process.env.ANTHROPIC_API_KEY ?? "";
|
|
66
|
-
if (apiKey.includes("
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const payload = decodeJWTPayload(jwtPart);
|
|
72
|
-
if (payload.organization_uuid) {
|
|
73
|
-
return payload.organization_uuid;
|
|
74
|
-
}
|
|
75
|
-
} catch {
|
|
77
|
+
if (apiKey.includes(".")) {
|
|
78
|
+
try {
|
|
79
|
+
const payload = decodeJWTPayload(apiKey);
|
|
80
|
+
if (payload.organization_uuid) {
|
|
81
|
+
return payload.organization_uuid;
|
|
76
82
|
}
|
|
83
|
+
} catch {
|
|
77
84
|
}
|
|
78
85
|
}
|
|
79
86
|
throw new Error(
|
|
@@ -82,6 +89,23 @@ function getOrgUUID() {
|
|
|
82
89
|
}
|
|
83
90
|
|
|
84
91
|
// src/http.ts
|
|
92
|
+
async function getProxyDispatcher() {
|
|
93
|
+
const proxyUrl = process.env.HTTPS_PROXY || process.env.HTTP_PROXY;
|
|
94
|
+
if (!proxyUrl) return void 0;
|
|
95
|
+
try {
|
|
96
|
+
const undici = await import("undici");
|
|
97
|
+
return new undici.ProxyAgent(proxyUrl);
|
|
98
|
+
} catch {
|
|
99
|
+
return void 0;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
var _dispatcher = null;
|
|
103
|
+
async function ensureDispatcher() {
|
|
104
|
+
if (_dispatcher === null) {
|
|
105
|
+
_dispatcher = await getProxyDispatcher();
|
|
106
|
+
}
|
|
107
|
+
return _dispatcher;
|
|
108
|
+
}
|
|
85
109
|
function createHttpClient(serverUrl, sessionToken) {
|
|
86
110
|
const baseUrl = serverUrl.replace(/\/$/, "");
|
|
87
111
|
async function request(path, init = {}) {
|
|
@@ -94,10 +118,15 @@ function createHttpClient(serverUrl, sessionToken) {
|
|
|
94
118
|
if (!headers["Content-Type"] && init.body && typeof init.body === "string") {
|
|
95
119
|
headers["Content-Type"] = "application/json";
|
|
96
120
|
}
|
|
97
|
-
const
|
|
121
|
+
const dispatcher = await ensureDispatcher();
|
|
122
|
+
const fetchOpts = {
|
|
98
123
|
...init,
|
|
99
124
|
headers
|
|
100
|
-
}
|
|
125
|
+
};
|
|
126
|
+
if (dispatcher) {
|
|
127
|
+
fetchOpts.dispatcher = dispatcher;
|
|
128
|
+
}
|
|
129
|
+
const res = await fetch(`${baseUrl}${path}`, fetchOpts);
|
|
101
130
|
if (!res.ok) {
|
|
102
131
|
let errorBody;
|
|
103
132
|
try {
|
|
@@ -124,11 +153,16 @@ function createHttpClient(serverUrl, sessionToken) {
|
|
|
124
153
|
if (sessionToken) {
|
|
125
154
|
headers["Authorization"] = `Bearer ${sessionToken}`;
|
|
126
155
|
}
|
|
127
|
-
const
|
|
156
|
+
const dispatcher = await ensureDispatcher();
|
|
157
|
+
const fetchOpts = {
|
|
128
158
|
method: "POST",
|
|
129
159
|
headers,
|
|
130
160
|
body: formData
|
|
131
|
-
}
|
|
161
|
+
};
|
|
162
|
+
if (dispatcher) {
|
|
163
|
+
fetchOpts.dispatcher = dispatcher;
|
|
164
|
+
}
|
|
165
|
+
const res = await fetch(`${baseUrl}${path}`, fetchOpts);
|
|
132
166
|
if (!res.ok) {
|
|
133
167
|
let errorBody;
|
|
134
168
|
try {
|
|
@@ -144,7 +178,12 @@ function createHttpClient(serverUrl, sessionToken) {
|
|
|
144
178
|
if (sessionToken) {
|
|
145
179
|
headers["Authorization"] = `Bearer ${sessionToken}`;
|
|
146
180
|
}
|
|
147
|
-
const
|
|
181
|
+
const dispatcher = await ensureDispatcher();
|
|
182
|
+
const fetchOpts = { headers };
|
|
183
|
+
if (dispatcher) {
|
|
184
|
+
fetchOpts.dispatcher = dispatcher;
|
|
185
|
+
}
|
|
186
|
+
const res = await fetch(`${baseUrl}${path}`, fetchOpts);
|
|
148
187
|
if (!res.ok) {
|
|
149
188
|
throw new Error(`HTTP ${res.status}: ${res.statusText}`);
|
|
150
189
|
}
|
|
@@ -538,7 +577,7 @@ function runCitty() {
|
|
|
538
577
|
dev: { type: "boolean", description: "Development mode (no HTTPS)" }
|
|
539
578
|
},
|
|
540
579
|
async run({ args }) {
|
|
541
|
-
const { startServer } = await import("./dist-
|
|
580
|
+
const { startServer } = await import("./dist-GANOIL6Z.js");
|
|
542
581
|
const extraArgs = [];
|
|
543
582
|
if (args.config) extraArgs.push("--config", args.config);
|
|
544
583
|
if (args.dev) extraArgs.push("--dev");
|
|
@@ -549,7 +588,7 @@ function runCitty() {
|
|
|
549
588
|
init: defineCommand({
|
|
550
589
|
meta: { name: "init", description: "Interactive setup wizard" },
|
|
551
590
|
async run() {
|
|
552
|
-
const { runInit } = await import("./dist-
|
|
591
|
+
const { runInit } = await import("./dist-GANOIL6Z.js");
|
|
553
592
|
await runInit();
|
|
554
593
|
}
|
|
555
594
|
}),
|
|
@@ -559,10 +598,27 @@ function runCitty() {
|
|
|
559
598
|
config: { type: "string", alias: "c", description: "Config file path" }
|
|
560
599
|
},
|
|
561
600
|
async run({ args }) {
|
|
562
|
-
const { generateServerPairingCode } = await import("./dist-
|
|
601
|
+
const { generateServerPairingCode } = await import("./dist-GANOIL6Z.js");
|
|
563
602
|
await generateServerPairingCode(args.config);
|
|
564
603
|
}
|
|
565
604
|
}),
|
|
605
|
+
install: defineCommand({
|
|
606
|
+
meta: { name: "install", description: "Install as persistent background service" },
|
|
607
|
+
args: {
|
|
608
|
+
config: { type: "string", alias: "c", description: "Config file path" }
|
|
609
|
+
},
|
|
610
|
+
async run({ args }) {
|
|
611
|
+
const { installDaemon } = await import("./dist-GANOIL6Z.js");
|
|
612
|
+
await installDaemon(args.config);
|
|
613
|
+
}
|
|
614
|
+
}),
|
|
615
|
+
uninstall: defineCommand({
|
|
616
|
+
meta: { name: "uninstall", description: "Remove background service" },
|
|
617
|
+
async run() {
|
|
618
|
+
const { uninstallDaemon } = await import("./dist-GANOIL6Z.js");
|
|
619
|
+
await uninstallDaemon();
|
|
620
|
+
}
|
|
621
|
+
}),
|
|
566
622
|
status: defineCommand({
|
|
567
623
|
meta: { name: "status", description: "Show server status" },
|
|
568
624
|
async run() {
|
|
@@ -586,21 +642,21 @@ function runCitty() {
|
|
|
586
642
|
cli: defineCommand({
|
|
587
643
|
meta: { name: "cli", description: "Wrap a CLI command" },
|
|
588
644
|
async run() {
|
|
589
|
-
const { wrapCli } = await import("./dist-
|
|
645
|
+
const { wrapCli } = await import("./dist-GANOIL6Z.js");
|
|
590
646
|
await wrapCli();
|
|
591
647
|
}
|
|
592
648
|
}),
|
|
593
649
|
mcp: defineCommand({
|
|
594
650
|
meta: { name: "mcp", description: "Wrap an MCP server" },
|
|
595
651
|
async run() {
|
|
596
|
-
const { wrapMcp } = await import("./dist-
|
|
652
|
+
const { wrapMcp } = await import("./dist-GANOIL6Z.js");
|
|
597
653
|
await wrapMcp();
|
|
598
654
|
}
|
|
599
655
|
}),
|
|
600
656
|
script: defineCommand({
|
|
601
657
|
meta: { name: "script", description: "Wrap a script" },
|
|
602
658
|
async run() {
|
|
603
|
-
const { wrapScript } = await import("./dist-
|
|
659
|
+
const { wrapScript } = await import("./dist-GANOIL6Z.js");
|
|
604
660
|
await wrapScript();
|
|
605
661
|
}
|
|
606
662
|
}),
|
|
@@ -610,7 +666,7 @@ function runCitty() {
|
|
|
610
666
|
path: { type: "positional", description: "Path to config file", required: true }
|
|
611
667
|
},
|
|
612
668
|
async run({ args }) {
|
|
613
|
-
const { wrapImport } = await import("./dist-
|
|
669
|
+
const { wrapImport } = await import("./dist-GANOIL6Z.js");
|
|
614
670
|
await wrapImport(args.path);
|
|
615
671
|
}
|
|
616
672
|
})
|
|
@@ -622,7 +678,7 @@ function runCitty() {
|
|
|
622
678
|
name: { type: "positional", description: "Tool name", required: true }
|
|
623
679
|
},
|
|
624
680
|
async run({ args }) {
|
|
625
|
-
const { unwrapTool } = await import("./dist-
|
|
681
|
+
const { unwrapTool } = await import("./dist-GANOIL6Z.js");
|
|
626
682
|
await unwrapTool(args.name);
|
|
627
683
|
}
|
|
628
684
|
});
|