flightdesk 0.4.1 → 0.4.3

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 (3) hide show
  1. package/main.js +58 -10
  2. package/main.js.map +3 -3
  3. package/package.json +1 -1
package/main.js CHANGED
@@ -3639,6 +3639,10 @@ function parseGitRemoteUrl(remoteUrl) {
3639
3639
  }
3640
3640
 
3641
3641
  // apps/cli/src/commands/register.ts
3642
+ var import_node_child_process2 = require("node:child_process");
3643
+ var import_node_fs = require("node:fs");
3644
+ var import_node_os = require("node:os");
3645
+ var import_node_path = require("node:path");
3642
3646
  async function registerCommand(taskId, options) {
3643
3647
  const { config, org: org2 } = requireActiveOrg();
3644
3648
  const api = FlightDeskAPI.fromConfig(config, org2);
@@ -3649,7 +3653,13 @@ async function registerCommand(taskId, options) {
3649
3653
  }
3650
3654
  let viewUrl = options.viewUrl;
3651
3655
  let teleportId = options.teleportId;
3652
- if (!process.stdin.isTTY) {
3656
+ if (options.prompt) {
3657
+ console.log("\u23F3 Starting Claude remote session...");
3658
+ const claudeOutput = await spawnClaudeRemote(options.prompt);
3659
+ const parsed = parseClaudeOutput(claudeOutput);
3660
+ viewUrl = viewUrl || parsed.viewUrl;
3661
+ teleportId = teleportId || parsed.teleportId;
3662
+ } else if (!process.stdin.isTTY) {
3653
3663
  console.log("\u23F3 Waiting for Claude session output...");
3654
3664
  const input = await readStdin();
3655
3665
  const parsed = parseClaudeOutput(input);
@@ -3694,6 +3704,44 @@ Task ID: ${actualTaskId}`);
3694
3704
  process.exit(1);
3695
3705
  }
3696
3706
  }
3707
+ function spawnClaudeRemote(prompt) {
3708
+ const tmpDir = (0, import_node_fs.mkdtempSync)((0, import_node_path.join)((0, import_node_os.tmpdir)(), "fd-claude-"));
3709
+ const tmpFile = (0, import_node_path.join)(tmpDir, "output.txt");
3710
+ const isMac = process.platform === "darwin";
3711
+ const escaped = prompt.replaceAll("'", `'"'"'`);
3712
+ const scriptArgs = isMac ? ["-q", tmpFile, "claude", "--remote", prompt] : ["-q", "-c", `claude --remote '${escaped}'`, tmpFile];
3713
+ return new Promise((resolve, reject) => {
3714
+ const child = (0, import_node_child_process2.spawn)("script", scriptArgs, {
3715
+ stdio: "inherit"
3716
+ // claude sees real TTY on all streams
3717
+ });
3718
+ child.on("close", (code) => {
3719
+ try {
3720
+ let raw = "";
3721
+ try {
3722
+ raw = (0, import_node_fs.readFileSync)(tmpFile, "utf8");
3723
+ } catch {
3724
+ }
3725
+ try {
3726
+ (0, import_node_fs.rmSync)(tmpDir, { recursive: true });
3727
+ } catch {
3728
+ }
3729
+ const output = raw.replace(/\x1b\[[0-9;]*[mGKHFJABCDr]/g, "").replace(/\r/g, "");
3730
+ if (code !== 0) {
3731
+ reject(new Error(`claude exited with code ${code}
3732
+ Output: ${output.slice(0, 500)}`));
3733
+ } else {
3734
+ resolve(output);
3735
+ }
3736
+ } catch (err) {
3737
+ reject(err);
3738
+ }
3739
+ });
3740
+ child.on("error", (err) => {
3741
+ reject(new Error(`Failed to spawn 'script' command: ${err.message}`));
3742
+ });
3743
+ });
3744
+ }
3697
3745
  function readStdin() {
3698
3746
  return new Promise((resolve) => {
3699
3747
  let data = "";
@@ -4360,7 +4408,7 @@ ${projects.length} project(s)`);
4360
4408
  }
4361
4409
 
4362
4410
  // apps/cli/src/commands/preview.ts
4363
- var import_node_child_process2 = require("node:child_process");
4411
+ var import_node_child_process3 = require("node:child_process");
4364
4412
  var path2 = __toESM(require("node:path"));
4365
4413
  var os2 = __toESM(require("node:os"));
4366
4414
  var fs2 = __toESM(require("node:fs"));
@@ -4474,7 +4522,7 @@ async function handleLogs(api, options) {
4474
4522
  `);
4475
4523
  validateSSHParams(instance);
4476
4524
  const sshCommand = `docker logs -f ${instance.containerId}`;
4477
- const ssh = (0, import_node_child_process2.spawn)("ssh", [
4525
+ const ssh = (0, import_node_child_process3.spawn)("ssh", [
4478
4526
  "-o",
4479
4527
  "StrictHostKeyChecking=no",
4480
4528
  "-o",
@@ -4514,7 +4562,7 @@ async function handleMount(api, options) {
4514
4562
  await new Promise((resolve) => setTimeout(resolve, 3e3));
4515
4563
  }
4516
4564
  try {
4517
- (0, import_node_child_process2.execSync)("which sshfs", { stdio: "ignore" });
4565
+ (0, import_node_child_process3.execSync)("which sshfs", { stdio: "ignore" });
4518
4566
  } catch {
4519
4567
  console.error("\u274C sshfs is not installed.");
4520
4568
  console.error("");
@@ -4535,7 +4583,7 @@ async function handleMount(api, options) {
4535
4583
  fs2.mkdirSync(mountDir, { recursive: true });
4536
4584
  }
4537
4585
  try {
4538
- const mounted = (0, import_node_child_process2.execSync)("mount", { encoding: "utf8" });
4586
+ const mounted = (0, import_node_child_process3.execSync)("mount", { encoding: "utf8" });
4539
4587
  if (mounted.includes(mountDir)) {
4540
4588
  console.log(`\u{1F4C1} Already mounted at ${mountDir}`);
4541
4589
  return;
@@ -4561,7 +4609,7 @@ async function handleMount(api, options) {
4561
4609
  mountDir
4562
4610
  ];
4563
4611
  try {
4564
- const result = (0, import_node_child_process2.spawnSync)("sshfs", sshfsArgs, { stdio: "inherit" });
4612
+ const result = (0, import_node_child_process3.spawnSync)("sshfs", sshfsArgs, { stdio: "inherit" });
4565
4613
  if (result.status !== 0) {
4566
4614
  throw new Error(`sshfs exited with code ${result.status}`);
4567
4615
  }
@@ -4595,9 +4643,9 @@ async function handleUnmount(_api, options) {
4595
4643
  try {
4596
4644
  let result;
4597
4645
  if (process.platform === "darwin") {
4598
- result = (0, import_node_child_process2.spawnSync)("umount", [mountDir], { stdio: "inherit" });
4646
+ result = (0, import_node_child_process3.spawnSync)("umount", [mountDir], { stdio: "inherit" });
4599
4647
  } else {
4600
- result = (0, import_node_child_process2.spawnSync)("fusermount", ["-u", mountDir], { stdio: "inherit" });
4648
+ result = (0, import_node_child_process3.spawnSync)("fusermount", ["-u", mountDir], { stdio: "inherit" });
4601
4649
  }
4602
4650
  if (result.status !== 0) {
4603
4651
  throw new Error(`Unmount exited with code ${result.status}`);
@@ -4637,7 +4685,7 @@ async function handleTeardown(api, options) {
4637
4685
 
4638
4686
  // apps/cli/src/main.ts
4639
4687
  var program2 = new Command();
4640
- program2.name("flightdesk").description("FlightDesk CLI - AI task management for Claude Code sessions").version("0.4.1").option("--dev", "Use local development API (localhost:3000)").option("--api <url>", "Use custom API URL");
4688
+ program2.name("flightdesk").description("FlightDesk CLI - AI task management for Claude Code sessions").version("0.4.3").option("--dev", "Use local development API (localhost:3000)").option("--api <url>", "Use custom API URL");
4641
4689
  program2.hook("preAction", () => {
4642
4690
  const opts = program2.opts();
4643
4691
  if (opts.api) {
@@ -4650,7 +4698,7 @@ program2.hook("preAction", () => {
4650
4698
  }
4651
4699
  });
4652
4700
  program2.command("init").description("Configure FlightDesk CLI with your API credentials").action(initCommand);
4653
- program2.command("register [task-id]").description("Register a Claude Code session with a FlightDesk task (auto-detects project from git repo)").option("-p, --project <id>", "Project ID (auto-detected from git repo if not provided)").option("--subproject <id>", "Subproject ID (required if project has subprojects configured)").option("--view-url <url>", "Claude Code session view URL").option("--teleport-id <id>", "Claude Code teleport ID").option("--title <title>", "Task title (creates new task if task-id not provided)").option("--description <description>", "Task description").action(registerCommand);
4701
+ program2.command("register [task-id]").description("Register a Claude Code session with a FlightDesk task (auto-detects project from git repo)").option("-p, --project <id>", "Project ID (auto-detected from git repo if not provided)").option("--subproject <id>", "Subproject ID (required if project has subprojects configured)").option("--view-url <url>", "Claude Code session view URL").option("--teleport-id <id>", "Claude Code teleport ID").option("--title <title>", "Task title (creates new task if task-id not provided)").option("--description <description>", "Task description").option("--prompt <prompt>", "Prompt to pass to claude --remote (avoids pipe detection issues)").action(registerCommand);
4654
4702
  var project = program2.command("project").description("Project management commands");
4655
4703
  project.command("list").description("List projects in the active organization").action(() => projectCommand("list", {}));
4656
4704
  var task = program2.command("task").description("Task management commands");