pencil-team 0.1.1 → 0.2.0
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 +70 -59
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2070,6 +2070,11 @@ var {
|
|
|
2070
2070
|
Help
|
|
2071
2071
|
} = import__.default;
|
|
2072
2072
|
|
|
2073
|
+
// src/index.ts
|
|
2074
|
+
import path4 from "path";
|
|
2075
|
+
import os3 from "os";
|
|
2076
|
+
import fs4 from "fs";
|
|
2077
|
+
|
|
2073
2078
|
// src/config.ts
|
|
2074
2079
|
import path from "path";
|
|
2075
2080
|
import os from "os";
|
|
@@ -9239,9 +9244,6 @@ function loadConfig2() {
|
|
|
9239
9244
|
}
|
|
9240
9245
|
|
|
9241
9246
|
// src/platform/opener.ts
|
|
9242
|
-
import { exec } from "child_process";
|
|
9243
|
-
import { promisify } from "util";
|
|
9244
|
-
var execAsync = promisify(exec);
|
|
9245
9247
|
function getPlatform() {
|
|
9246
9248
|
return process.platform;
|
|
9247
9249
|
}
|
|
@@ -9440,34 +9442,72 @@ class PenSync {
|
|
|
9440
9442
|
}
|
|
9441
9443
|
|
|
9442
9444
|
// src/platform/opener.ts
|
|
9443
|
-
import {
|
|
9444
|
-
import { promisify as promisify2 } from "util";
|
|
9445
|
+
import { execSync, spawn } from "child_process";
|
|
9445
9446
|
import path3 from "path";
|
|
9446
|
-
var execAsync2 = promisify2(exec2);
|
|
9447
9447
|
async function openWithPencil(filePath) {
|
|
9448
9448
|
const absPath = path3.resolve(filePath);
|
|
9449
9449
|
switch (process.platform) {
|
|
9450
9450
|
case "darwin":
|
|
9451
9451
|
try {
|
|
9452
|
-
|
|
9452
|
+
spawn("open", ["-a", "Pencil", absPath], { stdio: "ignore", detached: true }).unref();
|
|
9453
9453
|
} catch {
|
|
9454
|
-
|
|
9454
|
+
spawn("open", [absPath], { stdio: "ignore", detached: true }).unref();
|
|
9455
9455
|
}
|
|
9456
9456
|
break;
|
|
9457
9457
|
case "linux":
|
|
9458
|
-
|
|
9458
|
+
spawn("xdg-open", [absPath], { stdio: "ignore", detached: true }).unref();
|
|
9459
9459
|
break;
|
|
9460
9460
|
case "win32":
|
|
9461
|
-
|
|
9461
|
+
spawn("cmd", ["/c", "start", "", absPath], { stdio: "ignore", detached: true }).unref();
|
|
9462
9462
|
break;
|
|
9463
9463
|
default:
|
|
9464
9464
|
throw new Error(`Unsupported platform: ${process.platform}`);
|
|
9465
9465
|
}
|
|
9466
9466
|
}
|
|
9467
|
+
function closePencil(filePath) {
|
|
9468
|
+
const fileName = path3.basename(path3.resolve(filePath));
|
|
9469
|
+
try {
|
|
9470
|
+
switch (process.platform) {
|
|
9471
|
+
case "darwin": {
|
|
9472
|
+
const script = `
|
|
9473
|
+
tell application "System Events"
|
|
9474
|
+
if exists (process "Pencil") then
|
|
9475
|
+
tell process "Pencil"
|
|
9476
|
+
repeat with w in windows
|
|
9477
|
+
if name of w contains "${fileName}" then
|
|
9478
|
+
click button 1 of w
|
|
9479
|
+
end if
|
|
9480
|
+
end repeat
|
|
9481
|
+
end tell
|
|
9482
|
+
end if
|
|
9483
|
+
end tell
|
|
9484
|
+
`;
|
|
9485
|
+
execSync(`osascript -e '${script.replace(/'/g, "'\\''")}'`, { stdio: "ignore", timeout: 5000 });
|
|
9486
|
+
break;
|
|
9487
|
+
}
|
|
9488
|
+
case "linux":
|
|
9489
|
+
execSync(`wmctrl -c "${fileName}"`, { stdio: "ignore", timeout: 5000 });
|
|
9490
|
+
break;
|
|
9491
|
+
case "win32":
|
|
9492
|
+
execSync(`powershell -Command "Get-Process | Where-Object {$_.MainWindowTitle -like '*${fileName}*'} | ForEach-Object {$_.CloseMainWindow()}"`, { stdio: "ignore", timeout: 5000 });
|
|
9493
|
+
break;
|
|
9494
|
+
}
|
|
9495
|
+
} catch {}
|
|
9496
|
+
}
|
|
9467
9497
|
|
|
9468
9498
|
// src/index.ts
|
|
9499
|
+
var PENCIL_DIR = path4.join(os3.homedir(), ".pencil-team", "files");
|
|
9500
|
+
function ensurePencilDir() {
|
|
9501
|
+
if (!fs4.existsSync(PENCIL_DIR)) {
|
|
9502
|
+
fs4.mkdirSync(PENCIL_DIR, { recursive: true });
|
|
9503
|
+
}
|
|
9504
|
+
}
|
|
9505
|
+
function getTempPenPath(roomSlug) {
|
|
9506
|
+
ensurePencilDir();
|
|
9507
|
+
return path4.join(PENCIL_DIR, `${roomSlug}.pen`);
|
|
9508
|
+
}
|
|
9469
9509
|
var program2 = new Command;
|
|
9470
|
-
program2.name("pencil-team").description("Real-time collaboration for Pencil.dev .pen files").version("0.
|
|
9510
|
+
program2.name("pencil-team").description("Real-time collaboration for Pencil.dev .pen files").version("0.2.0");
|
|
9471
9511
|
program2.command("login").description("Authenticate with the Pencil Team server").option("-s, --server <url>", "Server URL", "https://pencil.codhash.com").option("-e, --email <email>", "Email address").option("-p, --password <password>", "Password").action(async (opts) => {
|
|
9472
9512
|
const serverUrl = opts.server;
|
|
9473
9513
|
let email = opts.email;
|
|
@@ -9517,15 +9557,20 @@ program2.command("status").description("Show current auth status").action(() =>
|
|
|
9517
9557
|
console.log("Not logged in. Run: pencil-team login");
|
|
9518
9558
|
}
|
|
9519
9559
|
});
|
|
9520
|
-
program2.command("sync").description("Sync a .pen file
|
|
9560
|
+
program2.command("sync").description("Sync and open a .pen file from a room").argument("<room>", "Room slug (from the web dashboard)").option("--no-open", "Do not open Pencil automatically").action(async (room, opts) => {
|
|
9521
9561
|
const config = loadConfig();
|
|
9522
9562
|
if (!config.token) {
|
|
9523
9563
|
console.error("Not logged in. Run: pencil-team login");
|
|
9524
9564
|
process.exit(1);
|
|
9525
9565
|
}
|
|
9526
|
-
|
|
9566
|
+
const filePath = getTempPenPath(room);
|
|
9567
|
+
if (!fs4.existsSync(filePath)) {
|
|
9568
|
+
fs4.writeFileSync(filePath, "{}");
|
|
9569
|
+
}
|
|
9570
|
+
console.log(`Syncing room: ${room}`);
|
|
9571
|
+
console.log(`Local file: ${filePath}`);
|
|
9527
9572
|
const sync = new PenSync({
|
|
9528
|
-
filePath
|
|
9573
|
+
filePath,
|
|
9529
9574
|
roomSlug: room,
|
|
9530
9575
|
onPresenceUpdate: (states) => {
|
|
9531
9576
|
const users = Array.from(states.values()).filter((s) => s.user).map((s) => s.user.name);
|
|
@@ -9534,65 +9579,31 @@ program2.command("sync").description("Sync a .pen file with a room").argument("<
|
|
|
9534
9579
|
}
|
|
9535
9580
|
},
|
|
9536
9581
|
onConnected: async () => {
|
|
9537
|
-
if (opts.open) {
|
|
9582
|
+
if (opts.open !== false) {
|
|
9538
9583
|
console.log("Opening Pencil...");
|
|
9539
|
-
await openWithPencil(
|
|
9584
|
+
await openWithPencil(filePath).catch((err) => console.error("Failed to open Pencil:", err.message));
|
|
9540
9585
|
}
|
|
9541
9586
|
}
|
|
9542
9587
|
});
|
|
9543
9588
|
sync.connect();
|
|
9544
9589
|
const shutdown = () => {
|
|
9545
9590
|
console.log(`
|
|
9546
|
-
|
|
9591
|
+
Shutting down...`);
|
|
9547
9592
|
sync.disconnect();
|
|
9593
|
+
console.log("Closing Pencil...");
|
|
9594
|
+
closePencil(filePath);
|
|
9595
|
+
try {
|
|
9596
|
+
if (fs4.existsSync(filePath)) {
|
|
9597
|
+
fs4.unlinkSync(filePath);
|
|
9598
|
+
console.log("Cleaned up temp file.");
|
|
9599
|
+
}
|
|
9600
|
+
} catch {}
|
|
9548
9601
|
process.exit(0);
|
|
9549
9602
|
};
|
|
9550
9603
|
process.on("SIGINT", shutdown);
|
|
9551
9604
|
process.on("SIGTERM", shutdown);
|
|
9552
9605
|
await new Promise(() => {});
|
|
9553
9606
|
});
|
|
9554
|
-
program2.command("open").description("Sync and open a .pen file in Pencil").argument("<file>", "Path to .pen file").argument("<room>", "Room slug").action(async (file, room) => {
|
|
9555
|
-
await program2.parseAsync(["node", "pencil-team", "sync", file, room, "--open"]);
|
|
9556
|
-
});
|
|
9557
|
-
program2.command("daemon").description("Run as a background daemon listening for commands").action(async () => {
|
|
9558
|
-
const config = loadConfig();
|
|
9559
|
-
if (!config.token) {
|
|
9560
|
-
console.error("Not logged in. Run: pencil-team login");
|
|
9561
|
-
process.exit(1);
|
|
9562
|
-
}
|
|
9563
|
-
console.log("Pencil Team daemon started. Listening for commands...");
|
|
9564
|
-
const wsUrl = config.serverUrl.replace("https://", "wss://").replace("http://", "ws://");
|
|
9565
|
-
const { default: WebSocket2 } = await import("ws");
|
|
9566
|
-
const ws = new WebSocket2(`${wsUrl}/ws/sync?token=${config.token}&room=__daemon__`);
|
|
9567
|
-
const activeSyncs = new Map;
|
|
9568
|
-
ws.on("message", async (data) => {
|
|
9569
|
-
try {
|
|
9570
|
-
const msg = JSON.parse(data.toString());
|
|
9571
|
-
if (msg.type === "command" && msg.action === "open_file") {
|
|
9572
|
-
const { filePath, roomSlug } = msg;
|
|
9573
|
-
activeSyncs.get(roomSlug)?.disconnect();
|
|
9574
|
-
const sync = new PenSync({
|
|
9575
|
-
filePath,
|
|
9576
|
-
roomSlug,
|
|
9577
|
-
onConnected: async () => {
|
|
9578
|
-
await openWithPencil(filePath).catch(console.error);
|
|
9579
|
-
}
|
|
9580
|
-
});
|
|
9581
|
-
sync.connect();
|
|
9582
|
-
activeSyncs.set(roomSlug, sync);
|
|
9583
|
-
console.log(`Syncing: ${filePath} \u2192 ${roomSlug}`);
|
|
9584
|
-
}
|
|
9585
|
-
} catch {}
|
|
9586
|
-
});
|
|
9587
|
-
ws.on("close", () => {
|
|
9588
|
-
console.log("Daemon disconnected. Exiting.");
|
|
9589
|
-
for (const sync of activeSyncs.values()) {
|
|
9590
|
-
sync.disconnect();
|
|
9591
|
-
}
|
|
9592
|
-
process.exit(1);
|
|
9593
|
-
});
|
|
9594
|
-
await new Promise(() => {});
|
|
9595
|
-
});
|
|
9596
9607
|
function readLine() {
|
|
9597
9608
|
return new Promise((resolve3) => {
|
|
9598
9609
|
let data = "";
|