junis 0.1.4 → 0.1.7
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/cli/index.js +96 -3
- package/dist/server/mcp.js +75 -0
- package/dist/server/stdio.js +75 -0
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -31,7 +31,7 @@ var require_package = __commonJS({
|
|
|
31
31
|
"package.json"(exports2, module2) {
|
|
32
32
|
module2.exports = {
|
|
33
33
|
name: "junis",
|
|
34
|
-
version: "0.1.
|
|
34
|
+
version: "0.1.7",
|
|
35
35
|
description: "One-line device control for AI agents",
|
|
36
36
|
bin: {
|
|
37
37
|
junis: "dist/cli/index.js"
|
|
@@ -673,6 +673,7 @@ function platform() {
|
|
|
673
673
|
return "linux";
|
|
674
674
|
}
|
|
675
675
|
var DeviceTools = class {
|
|
676
|
+
screenRecordPid = null;
|
|
676
677
|
register(server) {
|
|
677
678
|
server.tool(
|
|
678
679
|
"screen_capture",
|
|
@@ -762,6 +763,80 @@ var DeviceTools = class {
|
|
|
762
763
|
return { content: [{ type: "text", text: "\uD074\uB9BD\uBCF4\uB4DC \uC800\uC7A5 \uC644\uB8CC" }] };
|
|
763
764
|
}
|
|
764
765
|
);
|
|
766
|
+
server.tool(
|
|
767
|
+
"screen_record",
|
|
768
|
+
"\uD654\uBA74 \uB179\uD654 \uC2DC\uC791/\uC911\uC9C0 (macOS: screencapture -v, \uAE30\uD0C0: ffmpeg)",
|
|
769
|
+
{
|
|
770
|
+
action: import_zod4.z.enum(["start", "stop"]).describe("start: \uB179\uD654 \uC2DC\uC791, stop: \uB179\uD654 \uC911\uC9C0"),
|
|
771
|
+
output_path: import_zod4.z.string().optional().describe("\uC800\uC7A5 \uACBD\uB85C (start \uC2DC \uC0AC\uC6A9, \uAE30\uBCF8: /tmp/junis_record_<timestamp>.mp4)")
|
|
772
|
+
},
|
|
773
|
+
async ({ action, output_path }) => {
|
|
774
|
+
const p = platform();
|
|
775
|
+
if (action === "start") {
|
|
776
|
+
if (this.screenRecordPid) {
|
|
777
|
+
return { content: [{ type: "text", text: "\uC774\uBBF8 \uB179\uD654 \uC911\uC785\uB2C8\uB2E4." }] };
|
|
778
|
+
}
|
|
779
|
+
const tmpPath = output_path ?? `/tmp/junis_record_${Date.now()}.mp4`;
|
|
780
|
+
const { spawn } = await import("child_process");
|
|
781
|
+
const cmd = p === "mac" ? ["screencapture", ["-v", tmpPath]] : ["ffmpeg", ["-f", p === "win" ? "gdigrab" : "x11grab", "-i", p === "win" ? "desktop" : ":0.0", tmpPath]];
|
|
782
|
+
const child = spawn(cmd[0], cmd[1], { detached: true, stdio: "ignore" });
|
|
783
|
+
child.unref();
|
|
784
|
+
this.screenRecordPid = child.pid ?? null;
|
|
785
|
+
return { content: [{ type: "text", text: `\uB179\uD654 \uC2DC\uC791\uB428. \uC800\uC7A5 \uACBD\uB85C: ${tmpPath} (PID: ${this.screenRecordPid})` }] };
|
|
786
|
+
} else {
|
|
787
|
+
if (!this.screenRecordPid) {
|
|
788
|
+
return { content: [{ type: "text", text: "\uD604\uC7AC \uB179\uD654 \uC911\uC774 \uC544\uB2D9\uB2C8\uB2E4." }] };
|
|
789
|
+
}
|
|
790
|
+
try {
|
|
791
|
+
process.kill(this.screenRecordPid, "SIGINT");
|
|
792
|
+
} catch {
|
|
793
|
+
}
|
|
794
|
+
this.screenRecordPid = null;
|
|
795
|
+
return { content: [{ type: "text", text: "\uB179\uD654 \uC911\uC9C0\uB428." }] };
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
);
|
|
799
|
+
server.tool(
|
|
800
|
+
"location_get",
|
|
801
|
+
"\uD604\uC7AC \uC704\uCE58 \uC870\uD68C (macOS: CoreLocation CLI, \uAE30\uD0C0: IP \uAE30\uBC18 fallback)",
|
|
802
|
+
{},
|
|
803
|
+
async () => {
|
|
804
|
+
const p = platform();
|
|
805
|
+
if (p === "mac") {
|
|
806
|
+
try {
|
|
807
|
+
const { stdout } = await execAsync3("CoreLocationCLI -once -format '%latitude,%longitude'", { timeout: 1e4 });
|
|
808
|
+
const [lat, lon] = stdout.trim().split(",");
|
|
809
|
+
return { content: [{ type: "text", text: `\uC704\uB3C4: ${lat}, \uACBD\uB3C4: ${lon}` }] };
|
|
810
|
+
} catch {
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
const res = await fetch("https://ipapi.co/json/");
|
|
814
|
+
const data = await res.json();
|
|
815
|
+
return {
|
|
816
|
+
content: [{
|
|
817
|
+
type: "text",
|
|
818
|
+
text: `\uC704\uB3C4: ${data.latitude}, \uACBD\uB3C4: ${data.longitude}, \uB3C4\uC2DC: ${data.city}, \uAD6D\uAC00: ${data.country_name} (IP \uAE30\uBC18 \uCD94\uC815)`
|
|
819
|
+
}]
|
|
820
|
+
};
|
|
821
|
+
}
|
|
822
|
+
);
|
|
823
|
+
server.tool(
|
|
824
|
+
"audio_play",
|
|
825
|
+
"\uC624\uB514\uC624 \uD30C\uC77C \uC7AC\uC0DD (macOS: afplay, \uAE30\uD0C0: ffplay)",
|
|
826
|
+
{
|
|
827
|
+
file_path: import_zod4.z.string().describe("\uC7AC\uC0DD\uD560 \uC624\uB514\uC624 \uD30C\uC77C \uACBD\uB85C")
|
|
828
|
+
},
|
|
829
|
+
async ({ file_path }) => {
|
|
830
|
+
const p = platform();
|
|
831
|
+
const cmd = {
|
|
832
|
+
mac: `afplay "${file_path}"`,
|
|
833
|
+
win: `ffplay -nodisp -autoexit "${file_path}"`,
|
|
834
|
+
linux: `ffplay -nodisp -autoexit "${file_path}"`
|
|
835
|
+
}[p];
|
|
836
|
+
await execAsync3(cmd);
|
|
837
|
+
return { content: [{ type: "text", text: `\uC7AC\uC0DD \uC644\uB8CC: ${file_path}` }] };
|
|
838
|
+
}
|
|
839
|
+
);
|
|
765
840
|
}
|
|
766
841
|
};
|
|
767
842
|
|
|
@@ -1118,13 +1193,14 @@ import_commander.program.command("start", { isDefault: true }).description("Juni
|
|
|
1118
1193
|
console.log(" \u25C9 Status ....................... \u{1F7E2} online");
|
|
1119
1194
|
console.log("");
|
|
1120
1195
|
if (authResult.agent_id) {
|
|
1196
|
+
const workspaceName = `${deviceName} Workspace`;
|
|
1121
1197
|
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\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
1122
1198
|
console.log(" STEP 4 \xB7 Create AI Team");
|
|
1123
1199
|
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\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
1124
|
-
console.log(
|
|
1200
|
+
console.log(` \u25C9 Workspace created ............ ${workspaceName}`);
|
|
1125
1201
|
console.log(` \u25C9 Agent created ................ ${authResult.agent_name}`);
|
|
1126
1202
|
console.log(` \u25C9 Device linked ................ ${deviceName} \u2192 ${authResult.agent_name}`);
|
|
1127
|
-
console.log(" \u25C9 Tools assigned ...............
|
|
1203
|
+
console.log(" \u25C9 Tools assigned ............... call_device_mcp, list_device_mcp_tools");
|
|
1128
1204
|
console.log("");
|
|
1129
1205
|
}
|
|
1130
1206
|
} else {
|
|
@@ -1167,6 +1243,23 @@ import_commander.program.command("start", { isDefault: true }).description("Juni
|
|
|
1167
1243
|
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\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
1168
1244
|
console.log(" \u2705 ALL SET \u2014 Your AI can now control this device");
|
|
1169
1245
|
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\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
1246
|
+
const webUrl = process.env.JUNIS_WEB_URL ?? "https://junis.ai";
|
|
1247
|
+
console.log("");
|
|
1248
|
+
console.log(" Opening your AI team...");
|
|
1249
|
+
console.log(` \u2192 ${webUrl}`);
|
|
1250
|
+
console.log("\u250C\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\u2510");
|
|
1251
|
+
console.log("\u2502 \u2502");
|
|
1252
|
+
console.log("\u2502 Try asking your AI: \u2502");
|
|
1253
|
+
console.log("\u2502 \u2502");
|
|
1254
|
+
console.log('\u2502 "\uB370\uC2A4\uD06C\uD1B1 \uD30C\uC77C \uBAA9\uB85D \uBCF4\uC5EC\uC918" \u2502');
|
|
1255
|
+
console.log('\u2502 "\uD06C\uB86C\uC5D0\uC11C \uC624\uB298 \uB274\uC2A4 \uAC80\uC0C9\uD574\uC918" \u2502');
|
|
1256
|
+
console.log('\u2502 "\uCE74\uBA54\uB77C\uB85C \uC0AC\uC9C4 \uD55C \uC7A5 \uCC0D\uC5B4\uC918" \u2502');
|
|
1257
|
+
console.log('\u2502 "\uC774 \uC8FC\uD53C\uD130 \uB178\uD2B8\uBD81 3\uBC88 \uC140 \uC218\uC815\uD574\uC918" \u2502');
|
|
1258
|
+
console.log("\u2502 \u2502");
|
|
1259
|
+
console.log("\u2514\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\u2518");
|
|
1260
|
+
console.log("");
|
|
1261
|
+
console.log(" Device agent running. Press Ctrl+C to disconnect.");
|
|
1262
|
+
console.log("");
|
|
1170
1263
|
});
|
|
1171
1264
|
import_commander.program.command("logout").description("\uC778\uC99D \uC815\uBCF4 \uC0AD\uC81C").action(() => {
|
|
1172
1265
|
clearConfig();
|
package/dist/server/mcp.js
CHANGED
|
@@ -446,6 +446,7 @@ function platform() {
|
|
|
446
446
|
return "linux";
|
|
447
447
|
}
|
|
448
448
|
var DeviceTools = class {
|
|
449
|
+
screenRecordPid = null;
|
|
449
450
|
register(server) {
|
|
450
451
|
server.tool(
|
|
451
452
|
"screen_capture",
|
|
@@ -535,6 +536,80 @@ var DeviceTools = class {
|
|
|
535
536
|
return { content: [{ type: "text", text: "\uD074\uB9BD\uBCF4\uB4DC \uC800\uC7A5 \uC644\uB8CC" }] };
|
|
536
537
|
}
|
|
537
538
|
);
|
|
539
|
+
server.tool(
|
|
540
|
+
"screen_record",
|
|
541
|
+
"\uD654\uBA74 \uB179\uD654 \uC2DC\uC791/\uC911\uC9C0 (macOS: screencapture -v, \uAE30\uD0C0: ffmpeg)",
|
|
542
|
+
{
|
|
543
|
+
action: import_zod4.z.enum(["start", "stop"]).describe("start: \uB179\uD654 \uC2DC\uC791, stop: \uB179\uD654 \uC911\uC9C0"),
|
|
544
|
+
output_path: import_zod4.z.string().optional().describe("\uC800\uC7A5 \uACBD\uB85C (start \uC2DC \uC0AC\uC6A9, \uAE30\uBCF8: /tmp/junis_record_<timestamp>.mp4)")
|
|
545
|
+
},
|
|
546
|
+
async ({ action, output_path }) => {
|
|
547
|
+
const p = platform();
|
|
548
|
+
if (action === "start") {
|
|
549
|
+
if (this.screenRecordPid) {
|
|
550
|
+
return { content: [{ type: "text", text: "\uC774\uBBF8 \uB179\uD654 \uC911\uC785\uB2C8\uB2E4." }] };
|
|
551
|
+
}
|
|
552
|
+
const tmpPath = output_path ?? `/tmp/junis_record_${Date.now()}.mp4`;
|
|
553
|
+
const { spawn } = await import("child_process");
|
|
554
|
+
const cmd = p === "mac" ? ["screencapture", ["-v", tmpPath]] : ["ffmpeg", ["-f", p === "win" ? "gdigrab" : "x11grab", "-i", p === "win" ? "desktop" : ":0.0", tmpPath]];
|
|
555
|
+
const child = spawn(cmd[0], cmd[1], { detached: true, stdio: "ignore" });
|
|
556
|
+
child.unref();
|
|
557
|
+
this.screenRecordPid = child.pid ?? null;
|
|
558
|
+
return { content: [{ type: "text", text: `\uB179\uD654 \uC2DC\uC791\uB428. \uC800\uC7A5 \uACBD\uB85C: ${tmpPath} (PID: ${this.screenRecordPid})` }] };
|
|
559
|
+
} else {
|
|
560
|
+
if (!this.screenRecordPid) {
|
|
561
|
+
return { content: [{ type: "text", text: "\uD604\uC7AC \uB179\uD654 \uC911\uC774 \uC544\uB2D9\uB2C8\uB2E4." }] };
|
|
562
|
+
}
|
|
563
|
+
try {
|
|
564
|
+
process.kill(this.screenRecordPid, "SIGINT");
|
|
565
|
+
} catch {
|
|
566
|
+
}
|
|
567
|
+
this.screenRecordPid = null;
|
|
568
|
+
return { content: [{ type: "text", text: "\uB179\uD654 \uC911\uC9C0\uB428." }] };
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
);
|
|
572
|
+
server.tool(
|
|
573
|
+
"location_get",
|
|
574
|
+
"\uD604\uC7AC \uC704\uCE58 \uC870\uD68C (macOS: CoreLocation CLI, \uAE30\uD0C0: IP \uAE30\uBC18 fallback)",
|
|
575
|
+
{},
|
|
576
|
+
async () => {
|
|
577
|
+
const p = platform();
|
|
578
|
+
if (p === "mac") {
|
|
579
|
+
try {
|
|
580
|
+
const { stdout } = await execAsync3("CoreLocationCLI -once -format '%latitude,%longitude'", { timeout: 1e4 });
|
|
581
|
+
const [lat, lon] = stdout.trim().split(",");
|
|
582
|
+
return { content: [{ type: "text", text: `\uC704\uB3C4: ${lat}, \uACBD\uB3C4: ${lon}` }] };
|
|
583
|
+
} catch {
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
const res = await fetch("https://ipapi.co/json/");
|
|
587
|
+
const data = await res.json();
|
|
588
|
+
return {
|
|
589
|
+
content: [{
|
|
590
|
+
type: "text",
|
|
591
|
+
text: `\uC704\uB3C4: ${data.latitude}, \uACBD\uB3C4: ${data.longitude}, \uB3C4\uC2DC: ${data.city}, \uAD6D\uAC00: ${data.country_name} (IP \uAE30\uBC18 \uCD94\uC815)`
|
|
592
|
+
}]
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
);
|
|
596
|
+
server.tool(
|
|
597
|
+
"audio_play",
|
|
598
|
+
"\uC624\uB514\uC624 \uD30C\uC77C \uC7AC\uC0DD (macOS: afplay, \uAE30\uD0C0: ffplay)",
|
|
599
|
+
{
|
|
600
|
+
file_path: import_zod4.z.string().describe("\uC7AC\uC0DD\uD560 \uC624\uB514\uC624 \uD30C\uC77C \uACBD\uB85C")
|
|
601
|
+
},
|
|
602
|
+
async ({ file_path }) => {
|
|
603
|
+
const p = platform();
|
|
604
|
+
const cmd = {
|
|
605
|
+
mac: `afplay "${file_path}"`,
|
|
606
|
+
win: `ffplay -nodisp -autoexit "${file_path}"`,
|
|
607
|
+
linux: `ffplay -nodisp -autoexit "${file_path}"`
|
|
608
|
+
}[p];
|
|
609
|
+
await execAsync3(cmd);
|
|
610
|
+
return { content: [{ type: "text", text: `\uC7AC\uC0DD \uC644\uB8CC: ${file_path}` }] };
|
|
611
|
+
}
|
|
612
|
+
);
|
|
538
613
|
}
|
|
539
614
|
};
|
|
540
615
|
|
package/dist/server/stdio.js
CHANGED
|
@@ -435,6 +435,7 @@ function platform() {
|
|
|
435
435
|
return "linux";
|
|
436
436
|
}
|
|
437
437
|
var DeviceTools = class {
|
|
438
|
+
screenRecordPid = null;
|
|
438
439
|
register(server) {
|
|
439
440
|
server.tool(
|
|
440
441
|
"screen_capture",
|
|
@@ -524,6 +525,80 @@ var DeviceTools = class {
|
|
|
524
525
|
return { content: [{ type: "text", text: "\uD074\uB9BD\uBCF4\uB4DC \uC800\uC7A5 \uC644\uB8CC" }] };
|
|
525
526
|
}
|
|
526
527
|
);
|
|
528
|
+
server.tool(
|
|
529
|
+
"screen_record",
|
|
530
|
+
"\uD654\uBA74 \uB179\uD654 \uC2DC\uC791/\uC911\uC9C0 (macOS: screencapture -v, \uAE30\uD0C0: ffmpeg)",
|
|
531
|
+
{
|
|
532
|
+
action: import_zod4.z.enum(["start", "stop"]).describe("start: \uB179\uD654 \uC2DC\uC791, stop: \uB179\uD654 \uC911\uC9C0"),
|
|
533
|
+
output_path: import_zod4.z.string().optional().describe("\uC800\uC7A5 \uACBD\uB85C (start \uC2DC \uC0AC\uC6A9, \uAE30\uBCF8: /tmp/junis_record_<timestamp>.mp4)")
|
|
534
|
+
},
|
|
535
|
+
async ({ action, output_path }) => {
|
|
536
|
+
const p = platform();
|
|
537
|
+
if (action === "start") {
|
|
538
|
+
if (this.screenRecordPid) {
|
|
539
|
+
return { content: [{ type: "text", text: "\uC774\uBBF8 \uB179\uD654 \uC911\uC785\uB2C8\uB2E4." }] };
|
|
540
|
+
}
|
|
541
|
+
const tmpPath = output_path ?? `/tmp/junis_record_${Date.now()}.mp4`;
|
|
542
|
+
const { spawn } = await import("child_process");
|
|
543
|
+
const cmd = p === "mac" ? ["screencapture", ["-v", tmpPath]] : ["ffmpeg", ["-f", p === "win" ? "gdigrab" : "x11grab", "-i", p === "win" ? "desktop" : ":0.0", tmpPath]];
|
|
544
|
+
const child = spawn(cmd[0], cmd[1], { detached: true, stdio: "ignore" });
|
|
545
|
+
child.unref();
|
|
546
|
+
this.screenRecordPid = child.pid ?? null;
|
|
547
|
+
return { content: [{ type: "text", text: `\uB179\uD654 \uC2DC\uC791\uB428. \uC800\uC7A5 \uACBD\uB85C: ${tmpPath} (PID: ${this.screenRecordPid})` }] };
|
|
548
|
+
} else {
|
|
549
|
+
if (!this.screenRecordPid) {
|
|
550
|
+
return { content: [{ type: "text", text: "\uD604\uC7AC \uB179\uD654 \uC911\uC774 \uC544\uB2D9\uB2C8\uB2E4." }] };
|
|
551
|
+
}
|
|
552
|
+
try {
|
|
553
|
+
process.kill(this.screenRecordPid, "SIGINT");
|
|
554
|
+
} catch {
|
|
555
|
+
}
|
|
556
|
+
this.screenRecordPid = null;
|
|
557
|
+
return { content: [{ type: "text", text: "\uB179\uD654 \uC911\uC9C0\uB428." }] };
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
);
|
|
561
|
+
server.tool(
|
|
562
|
+
"location_get",
|
|
563
|
+
"\uD604\uC7AC \uC704\uCE58 \uC870\uD68C (macOS: CoreLocation CLI, \uAE30\uD0C0: IP \uAE30\uBC18 fallback)",
|
|
564
|
+
{},
|
|
565
|
+
async () => {
|
|
566
|
+
const p = platform();
|
|
567
|
+
if (p === "mac") {
|
|
568
|
+
try {
|
|
569
|
+
const { stdout } = await execAsync3("CoreLocationCLI -once -format '%latitude,%longitude'", { timeout: 1e4 });
|
|
570
|
+
const [lat, lon] = stdout.trim().split(",");
|
|
571
|
+
return { content: [{ type: "text", text: `\uC704\uB3C4: ${lat}, \uACBD\uB3C4: ${lon}` }] };
|
|
572
|
+
} catch {
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
const res = await fetch("https://ipapi.co/json/");
|
|
576
|
+
const data = await res.json();
|
|
577
|
+
return {
|
|
578
|
+
content: [{
|
|
579
|
+
type: "text",
|
|
580
|
+
text: `\uC704\uB3C4: ${data.latitude}, \uACBD\uB3C4: ${data.longitude}, \uB3C4\uC2DC: ${data.city}, \uAD6D\uAC00: ${data.country_name} (IP \uAE30\uBC18 \uCD94\uC815)`
|
|
581
|
+
}]
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
);
|
|
585
|
+
server.tool(
|
|
586
|
+
"audio_play",
|
|
587
|
+
"\uC624\uB514\uC624 \uD30C\uC77C \uC7AC\uC0DD (macOS: afplay, \uAE30\uD0C0: ffplay)",
|
|
588
|
+
{
|
|
589
|
+
file_path: import_zod4.z.string().describe("\uC7AC\uC0DD\uD560 \uC624\uB514\uC624 \uD30C\uC77C \uACBD\uB85C")
|
|
590
|
+
},
|
|
591
|
+
async ({ file_path }) => {
|
|
592
|
+
const p = platform();
|
|
593
|
+
const cmd = {
|
|
594
|
+
mac: `afplay "${file_path}"`,
|
|
595
|
+
win: `ffplay -nodisp -autoexit "${file_path}"`,
|
|
596
|
+
linux: `ffplay -nodisp -autoexit "${file_path}"`
|
|
597
|
+
}[p];
|
|
598
|
+
await execAsync3(cmd);
|
|
599
|
+
return { content: [{ type: "text", text: `\uC7AC\uC0DD \uC644\uB8CC: ${file_path}` }] };
|
|
600
|
+
}
|
|
601
|
+
);
|
|
527
602
|
}
|
|
528
603
|
};
|
|
529
604
|
|