junis 0.1.5 → 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 +79 -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 {
|
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
|
|