@michael_magdy/mic-drop 0.1.1 → 0.1.2

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 +93 -52
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -27,11 +27,11 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
27
  var import_commander = require("commander");
28
28
 
29
29
  // package.json
30
- var version = "0.1.1";
30
+ var version = "0.1.2";
31
31
 
32
32
  // src/commands/setup.ts
33
33
  var import_prompts = require("@inquirer/prompts");
34
- var import_path5 = __toESM(require("path"));
34
+ var import_path6 = __toESM(require("path"));
35
35
 
36
36
  // src/config/credentials.ts
37
37
  var import_keytar = __toESM(require("keytar"));
@@ -323,18 +323,58 @@ function sleep(ms) {
323
323
  return new Promise((resolve) => setTimeout(resolve, ms));
324
324
  }
325
325
 
326
- // src/terminal/launchers/iterm.ts
326
+ // src/terminal/launchers/warp-windows.ts
327
+ var import_fs3 = __toESM(require("fs"));
328
+ var import_path3 = __toESM(require("path"));
327
329
  var import_child_process2 = require("child_process");
330
+ var WarpWindowsLauncher = class {
331
+ name = "warp";
332
+ platform = ["win32"];
333
+ async isAvailable() {
334
+ try {
335
+ (0, import_child_process2.execSync)("where warp-terminal", { stdio: "ignore" });
336
+ return true;
337
+ } catch {
338
+ return false;
339
+ }
340
+ }
341
+ async launch({ workingDirectory, command }) {
342
+ const scriptPath = import_path3.default.join(workingDirectory, ".start-claude.sh");
343
+ import_fs3.default.writeFileSync(scriptPath, `#!/bin/bash
344
+ ${command}
345
+ `);
346
+ (0, import_child_process2.spawn)("warp-terminal", ["--working-directory", workingDirectory], {
347
+ detached: true,
348
+ stdio: "ignore",
349
+ shell: true
350
+ }).unref();
351
+ await sleep2(2e3);
352
+ const psScript = [
353
+ `Add-Type -AssemblyName System.Windows.Forms`,
354
+ `[System.Windows.Forms.SendKeys]::SendWait("bash .start-claude.sh{ENTER}")`
355
+ ].join("; ");
356
+ (0, import_child_process2.spawn)("powershell", ["-NoProfile", "-Command", psScript], {
357
+ detached: true,
358
+ stdio: "ignore"
359
+ }).unref();
360
+ }
361
+ };
362
+ function sleep2(ms) {
363
+ return new Promise((resolve) => setTimeout(resolve, ms));
364
+ }
365
+
366
+ // src/terminal/launchers/iterm.ts
367
+ var import_child_process3 = require("child_process");
328
368
  var ITermLauncher = class {
329
369
  name = "iterm";
330
370
  platform = ["darwin"];
331
371
  async isAvailable() {
332
372
  try {
333
- (0, import_child_process2.execSync)("test -d '/Applications/iTerm.app'", { stdio: "ignore" });
373
+ (0, import_child_process3.execSync)("test -d '/Applications/iTerm.app'", { stdio: "ignore" });
334
374
  return true;
335
375
  } catch {
336
376
  try {
337
- (0, import_child_process2.execSync)("test -d '/Applications/iTerm2.app'", { stdio: "ignore" });
377
+ (0, import_child_process3.execSync)("test -d '/Applications/iTerm2.app'", { stdio: "ignore" });
338
378
  return true;
339
379
  } catch {
340
380
  return false;
@@ -352,12 +392,12 @@ tell application "iTerm"
352
392
  write text "cd '${escapedDir}' && ${escapedCmd}"
353
393
  end tell
354
394
  end tell`;
355
- (0, import_child_process2.spawn)("osascript", ["-e", script], { detached: true, stdio: "ignore" }).unref();
395
+ (0, import_child_process3.spawn)("osascript", ["-e", script], { detached: true, stdio: "ignore" }).unref();
356
396
  }
357
397
  };
358
398
 
359
399
  // src/terminal/launchers/terminal-app.ts
360
- var import_child_process3 = require("child_process");
400
+ var import_child_process4 = require("child_process");
361
401
  var TerminalAppLauncher = class {
362
402
  name = "terminal";
363
403
  platform = ["darwin"];
@@ -372,25 +412,25 @@ tell application "Terminal"
372
412
  activate
373
413
  do script "cd '${escapedDir}' && ${escapedCmd}"
374
414
  end tell`;
375
- (0, import_child_process3.spawn)("osascript", ["-e", script], { detached: true, stdio: "ignore" }).unref();
415
+ (0, import_child_process4.spawn)("osascript", ["-e", script], { detached: true, stdio: "ignore" }).unref();
376
416
  }
377
417
  };
378
418
 
379
419
  // src/terminal/launchers/gnome-terminal.ts
380
- var import_child_process4 = require("child_process");
420
+ var import_child_process5 = require("child_process");
381
421
  var GnomeTerminalLauncher = class {
382
422
  name = "gnome-terminal";
383
423
  platform = ["linux"];
384
424
  async isAvailable() {
385
425
  try {
386
- (0, import_child_process4.execSync)("which gnome-terminal", { stdio: "ignore" });
426
+ (0, import_child_process5.execSync)("which gnome-terminal", { stdio: "ignore" });
387
427
  return true;
388
428
  } catch {
389
429
  return false;
390
430
  }
391
431
  }
392
432
  async launch({ workingDirectory, command }) {
393
- (0, import_child_process4.spawn)(
433
+ (0, import_child_process5.spawn)(
394
434
  "gnome-terminal",
395
435
  ["--working-directory", workingDirectory, "--", "bash", "-c", command],
396
436
  { detached: true, stdio: "ignore" }
@@ -399,20 +439,20 @@ var GnomeTerminalLauncher = class {
399
439
  };
400
440
 
401
441
  // src/terminal/launchers/konsole.ts
402
- var import_child_process5 = require("child_process");
442
+ var import_child_process6 = require("child_process");
403
443
  var KonsoleLauncher = class {
404
444
  name = "konsole";
405
445
  platform = ["linux"];
406
446
  async isAvailable() {
407
447
  try {
408
- (0, import_child_process5.execSync)("which konsole", { stdio: "ignore" });
448
+ (0, import_child_process6.execSync)("which konsole", { stdio: "ignore" });
409
449
  return true;
410
450
  } catch {
411
451
  return false;
412
452
  }
413
453
  }
414
454
  async launch({ workingDirectory, command }) {
415
- (0, import_child_process5.spawn)("konsole", ["--workdir", workingDirectory, "-e", command], {
455
+ (0, import_child_process6.spawn)("konsole", ["--workdir", workingDirectory, "-e", command], {
416
456
  detached: true,
417
457
  stdio: "ignore"
418
458
  }).unref();
@@ -420,20 +460,20 @@ var KonsoleLauncher = class {
420
460
  };
421
461
 
422
462
  // src/terminal/launchers/windows-terminal.ts
423
- var import_child_process6 = require("child_process");
463
+ var import_child_process7 = require("child_process");
424
464
  var WindowsTerminalLauncher = class {
425
465
  name = "windows-terminal";
426
466
  platform = ["win32"];
427
467
  async isAvailable() {
428
468
  try {
429
- (0, import_child_process6.execSync)("where wt", { stdio: "ignore" });
469
+ (0, import_child_process7.execSync)("where wt", { stdio: "ignore" });
430
470
  return true;
431
471
  } catch {
432
472
  return false;
433
473
  }
434
474
  }
435
475
  async launch({ workingDirectory, command }) {
436
- (0, import_child_process6.spawn)("wt", ["-d", workingDirectory, "powershell", "-Command", command], {
476
+ (0, import_child_process7.spawn)("wt", ["-d", workingDirectory, "powershell", "-Command", command], {
437
477
  detached: true,
438
478
  stdio: "ignore"
439
479
  }).unref();
@@ -443,6 +483,7 @@ var WindowsTerminalLauncher = class {
443
483
  // src/terminal/registry.ts
444
484
  var ALL_LAUNCHERS = [
445
485
  new WarpLauncher(),
486
+ new WarpWindowsLauncher(),
446
487
  new ITermLauncher(),
447
488
  new TerminalAppLauncher(),
448
489
  new GnomeTerminalLauncher(),
@@ -472,15 +513,15 @@ async function getAvailableLaunchers() {
472
513
  }
473
514
 
474
515
  // src/git/gitignore.ts
475
- var import_fs3 = __toESM(require("fs"));
476
- var import_path3 = __toESM(require("path"));
516
+ var import_fs4 = __toESM(require("fs"));
517
+ var import_path4 = __toESM(require("path"));
477
518
  function ensureGitignoreEntry(repoRoot, entry) {
478
- const gitignorePath = import_path3.default.join(repoRoot, ".gitignore");
519
+ const gitignorePath = import_path4.default.join(repoRoot, ".gitignore");
479
520
  const entryNorm = entry.endsWith("/") ? entry : entry + "/";
480
521
  const entryBase = entry.replace(/\/$/, "");
481
522
  let existing = "";
482
- if (import_fs3.default.existsSync(gitignorePath)) {
483
- existing = import_fs3.default.readFileSync(gitignorePath, "utf-8");
523
+ if (import_fs4.default.existsSync(gitignorePath)) {
524
+ existing = import_fs4.default.readFileSync(gitignorePath, "utf-8");
484
525
  const lines = existing.split("\n");
485
526
  for (const line of lines) {
486
527
  const trimmed = line.trim();
@@ -490,12 +531,12 @@ function ensureGitignoreEntry(repoRoot, entry) {
490
531
  }
491
532
  }
492
533
  const toAppend = existing.endsWith("\n") || existing === "" ? entryNorm + "\n" : "\n" + entryNorm + "\n";
493
- import_fs3.default.appendFileSync(gitignorePath, toAppend, "utf-8");
534
+ import_fs4.default.appendFileSync(gitignorePath, toAppend, "utf-8");
494
535
  }
495
536
 
496
537
  // src/git/worktree.ts
497
- var import_fs4 = __toESM(require("fs"));
498
- var import_path4 = __toESM(require("path"));
538
+ var import_fs5 = __toESM(require("fs"));
539
+ var import_path5 = __toESM(require("path"));
499
540
  var import_simple_git = __toESM(require("simple-git"));
500
541
  var WorktreeExistsError = class extends Error {
501
542
  constructor(targetDir) {
@@ -519,14 +560,14 @@ async function resolveRepoRoot(startDir) {
519
560
  async function createWorktree(opts) {
520
561
  const { repoRoot, targetDir, branchName, baseBranch } = opts;
521
562
  const git = (0, import_simple_git.default)(repoRoot);
522
- if (import_fs4.default.existsSync(targetDir)) {
563
+ if (import_fs5.default.existsSync(targetDir)) {
523
564
  throw new WorktreeExistsError(targetDir);
524
565
  }
525
566
  await git.raw(["worktree", "prune"]);
526
567
  await git.fetch("origin", baseBranch);
527
568
  const branchSummary = await git.branch(["-a"]);
528
569
  const branchExists = branchName in branchSummary.branches || `remotes/origin/${branchName}` in branchSummary.branches;
529
- import_fs4.default.mkdirSync(import_path4.default.dirname(targetDir), { recursive: true });
570
+ import_fs5.default.mkdirSync(import_path5.default.dirname(targetDir), { recursive: true });
530
571
  if (branchExists) {
531
572
  await git.raw(["worktree", "add", targetDir, branchName]);
532
573
  } else {
@@ -549,34 +590,34 @@ async function createWorktree(opts) {
549
590
  async function excludeFromWorktree(worktreeDir, entries) {
550
591
  const git = (0, import_simple_git.default)(worktreeDir);
551
592
  const gitDir = (await git.revparse(["--git-dir"])).trim();
552
- const absoluteGitDir = import_path4.default.isAbsolute(gitDir) ? gitDir : import_path4.default.join(worktreeDir, gitDir);
553
- const excludePath = import_path4.default.join(absoluteGitDir, "info", "exclude");
554
- import_fs4.default.mkdirSync(import_path4.default.dirname(excludePath), { recursive: true });
555
- const existing = import_fs4.default.existsSync(excludePath) ? import_fs4.default.readFileSync(excludePath, "utf-8") : "";
593
+ const absoluteGitDir = import_path5.default.isAbsolute(gitDir) ? gitDir : import_path5.default.join(worktreeDir, gitDir);
594
+ const excludePath = import_path5.default.join(absoluteGitDir, "info", "exclude");
595
+ import_fs5.default.mkdirSync(import_path5.default.dirname(excludePath), { recursive: true });
596
+ const existing = import_fs5.default.existsSync(excludePath) ? import_fs5.default.readFileSync(excludePath, "utf-8") : "";
556
597
  const existingLines = existing.split("\n");
557
598
  const toAdd = entries.filter((e) => !existingLines.includes(e));
558
599
  if (toAdd.length > 0) {
559
- import_fs4.default.appendFileSync(excludePath, toAdd.join("\n") + "\n", "utf-8");
600
+ import_fs5.default.appendFileSync(excludePath, toAdd.join("\n") + "\n", "utf-8");
560
601
  }
561
602
  }
562
603
  function copyProjectFiles(repoRoot, targetDir, copyFiles, copyDirs) {
563
604
  const copied = [];
564
605
  const missing = [];
565
606
  for (const file of copyFiles) {
566
- const src = import_path4.default.join(repoRoot, file);
567
- const dest = import_path4.default.join(targetDir, file);
568
- if (import_fs4.default.existsSync(src)) {
569
- import_fs4.default.mkdirSync(import_path4.default.dirname(dest), { recursive: true });
570
- import_fs4.default.copyFileSync(src, dest);
607
+ const src = import_path5.default.join(repoRoot, file);
608
+ const dest = import_path5.default.join(targetDir, file);
609
+ if (import_fs5.default.existsSync(src)) {
610
+ import_fs5.default.mkdirSync(import_path5.default.dirname(dest), { recursive: true });
611
+ import_fs5.default.copyFileSync(src, dest);
571
612
  copied.push(file);
572
613
  } else {
573
614
  missing.push(file);
574
615
  }
575
616
  }
576
617
  for (const dir of copyDirs) {
577
- const src = import_path4.default.join(repoRoot, dir);
578
- const dest = import_path4.default.join(targetDir, dir);
579
- if (import_fs4.default.existsSync(src) && import_fs4.default.statSync(src).isDirectory()) {
618
+ const src = import_path5.default.join(repoRoot, dir);
619
+ const dest = import_path5.default.join(targetDir, dir);
620
+ if (import_fs5.default.existsSync(src) && import_fs5.default.statSync(src).isDirectory()) {
580
621
  copyDirRecursive(src, dest);
581
622
  copied.push(dir + "/");
582
623
  } else {
@@ -586,14 +627,14 @@ function copyProjectFiles(repoRoot, targetDir, copyFiles, copyDirs) {
586
627
  return { copied, missing };
587
628
  }
588
629
  function copyDirRecursive(src, dest) {
589
- import_fs4.default.mkdirSync(dest, { recursive: true });
590
- for (const entry of import_fs4.default.readdirSync(src, { withFileTypes: true })) {
591
- const srcPath = import_path4.default.join(src, entry.name);
592
- const destPath = import_path4.default.join(dest, entry.name);
630
+ import_fs5.default.mkdirSync(dest, { recursive: true });
631
+ for (const entry of import_fs5.default.readdirSync(src, { withFileTypes: true })) {
632
+ const srcPath = import_path5.default.join(src, entry.name);
633
+ const destPath = import_path5.default.join(dest, entry.name);
593
634
  if (entry.isDirectory()) {
594
635
  copyDirRecursive(srcPath, destPath);
595
636
  } else {
596
- import_fs4.default.copyFileSync(srcPath, destPath);
637
+ import_fs5.default.copyFileSync(srcPath, destPath);
597
638
  }
598
639
  }
599
640
  }
@@ -741,15 +782,15 @@ async function runSetup() {
741
782
  cliFlags: cliFlags.trim()
742
783
  };
743
784
  saveProjectConfig(repoRoot, newConfig);
744
- logger.success(`Config written to ${import_path5.default.join(repoRoot, ".worktree.json")}`);
785
+ logger.success(`Config written to ${import_path6.default.join(repoRoot, ".worktree.json")}`);
745
786
  ensureGitignoreEntry(repoRoot, newConfig.worktreesDir);
746
787
  logger.success(`.gitignore updated with ${newConfig.worktreesDir}/`);
747
788
  console.log("\nSetup complete. Run: mic-drop PROJ-123\n");
748
789
  }
749
790
 
750
791
  // src/commands/run.ts
751
- var import_path6 = __toESM(require("path"));
752
- var import_fs5 = __toESM(require("fs"));
792
+ var import_path7 = __toESM(require("path"));
793
+ var import_fs6 = __toESM(require("fs"));
753
794
 
754
795
  // src/utils/slugify.ts
755
796
  var MAX_DESC_LENGTH = 60;
@@ -803,8 +844,8 @@ async function runTicket(issueKey, opts) {
803
844
  });
804
845
  logger.detail("Title", issue.title);
805
846
  const branchName = buildBranchName(issueKey, issue.title);
806
- const worktreesRoot = import_path6.default.isAbsolute(config.worktreesDir) ? config.worktreesDir : import_path6.default.join(repoRoot, config.worktreesDir);
807
- const targetDir = import_path6.default.join(worktreesRoot, issueKey);
847
+ const worktreesRoot = import_path7.default.isAbsolute(config.worktreesDir) ? config.worktreesDir : import_path7.default.join(repoRoot, config.worktreesDir);
848
+ const targetDir = import_path7.default.join(worktreesRoot, issueKey);
808
849
  logger.step("Preparing worktree...");
809
850
  logger.detail("Branch", branchName);
810
851
  logger.detail("Base", `origin/${config.baseBranch}`);
@@ -841,8 +882,8 @@ async function runTicket(issueKey, opts) {
841
882
  for (const f of missing) logger.warn(`Not found, skipped: ${f}`);
842
883
  }
843
884
  const ticketContent = formatTicketFile(issue, config.baseBranch);
844
- const ticketFile = import_path6.default.join(targetDir, ".ticket.md");
845
- import_fs5.default.writeFileSync(ticketFile, ticketContent, "utf-8");
885
+ const ticketFile = import_path7.default.join(targetDir, ".ticket.md");
886
+ import_fs6.default.writeFileSync(ticketFile, ticketContent, "utf-8");
846
887
  logger.success("Wrote .ticket.md");
847
888
  await excludeFromWorktree(targetDir, [".ticket.md", ".start-claude.sh"]);
848
889
  ensureGitignoreEntry(repoRoot, config.worktreesDir);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@michael_magdy/mic-drop",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "author": "Michael Magdy",
5
5
  "description": "Turn a Jira ticket into an isolated git worktree with Claude Code running automatically — in one command.",
6
6
  "type": "commonjs",