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.
Files changed (2) hide show
  1. package/dist/index.js +70 -59
  2. 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 { exec as exec2 } from "child_process";
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
- await execAsync2(`open -a "Pencil" "${absPath}"`);
9452
+ spawn("open", ["-a", "Pencil", absPath], { stdio: "ignore", detached: true }).unref();
9453
9453
  } catch {
9454
- await execAsync2(`open "${absPath}"`);
9454
+ spawn("open", [absPath], { stdio: "ignore", detached: true }).unref();
9455
9455
  }
9456
9456
  break;
9457
9457
  case "linux":
9458
- await execAsync2(`xdg-open "${absPath}"`);
9458
+ spawn("xdg-open", [absPath], { stdio: "ignore", detached: true }).unref();
9459
9459
  break;
9460
9460
  case "win32":
9461
- await execAsync2(`start "" "${absPath}"`);
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.1.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 with a room").argument("<file>", "Path to .pen file").argument("<room>", "Room slug").option("--open", "Open Pencil after connecting").action(async (file, room, opts) => {
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
- console.log(`Syncing ${file} \u2192 room:${room}`);
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: file,
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(file).catch((err) => console.error("Failed to open Pencil:", err.message));
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
- Disconnecting...`);
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 = "";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pencil-team",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "pencil-team": "dist/index.js"