claude-queue 1.0.0 → 1.0.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/cli.js +101 -10
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1,4 +1,10 @@
1
1
  #!/usr/bin/env node
2
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
3
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
4
+ }) : x)(function(x) {
5
+ if (typeof require !== "undefined") return require.apply(this, arguments);
6
+ throw Error('Dynamic require of "' + x + '" is not supported');
7
+ });
2
8
 
3
9
  // src/index.ts
4
10
  import { program } from "commander";
@@ -49,6 +55,19 @@ function getRunningPid() {
49
55
  return null;
50
56
  }
51
57
  }
58
+ function findServerPidByPort(port) {
59
+ try {
60
+ const { execSync } = __require("child_process");
61
+ const result = execSync(`lsof -ti tcp:${port}`, { encoding: "utf-8" }).trim();
62
+ if (result) {
63
+ const pids = result.split("\n").map((p) => parseInt(p.trim()));
64
+ return pids[0] || null;
65
+ }
66
+ return null;
67
+ } catch {
68
+ return null;
69
+ }
70
+ }
52
71
  function savePid(pid) {
53
72
  ensureKanbanDir();
54
73
  writeFileSync(PID_FILE, pid.toString());
@@ -193,11 +212,11 @@ function getSkillPath() {
193
212
  }
194
213
  throw new Error("Skill file not found. Run 'pnpm build' first.");
195
214
  }
196
- function installSkills() {
215
+ function installSkills(force = false) {
197
216
  const queueSkillDir = join3(SKILLS_DIR, "queue");
198
217
  const queueSkillFile = join3(queueSkillDir, "SKILL.md");
199
- if (existsSync2(queueSkillFile)) {
200
- return;
218
+ if (existsSync2(queueSkillFile) && !force) {
219
+ return false;
201
220
  }
202
221
  if (!existsSync2(SKILLS_DIR)) {
203
222
  mkdirSync2(SKILLS_DIR, { recursive: true });
@@ -209,6 +228,7 @@ function installSkills() {
209
228
  const skillContent = readFileSync2(skillSourcePath, "utf-8");
210
229
  writeFileSync2(queueSkillFile, skillContent);
211
230
  console.log("\u2713 Installed /queue skill to ~/.claude/skills/queue/");
231
+ return true;
212
232
  }
213
233
  function removeMcp() {
214
234
  const settingsPath = join3(CLAUDE_DIR, "settings.json");
@@ -287,7 +307,7 @@ async function runDoctor(port, fix) {
287
307
  console.log(" \u2192 Created settings.json with MCP config");
288
308
  }
289
309
  }
290
- const skillPath = join4(SKILLS_DIR, "kanban", "SKILL.md");
310
+ const skillPath = join4(SKILLS_DIR, "queue", "SKILL.md");
291
311
  if (existsSync3(skillPath)) {
292
312
  console.log("\u2705 /queue skill installed");
293
313
  } else {
@@ -304,7 +324,7 @@ async function runDoctor(port, fix) {
304
324
  console.log("\u26A0\uFE0F Queue data directory not created yet");
305
325
  warnings++;
306
326
  }
307
- const dbPath = join4(KANBAN_DIR, "kanban.db");
327
+ const dbPath = join4(KANBAN_DIR, "queue.db");
308
328
  if (existsSync3(dbPath)) {
309
329
  const stats = await import("fs/promises").then((fs) => fs.stat(dbPath));
310
330
  const sizeMB = (stats.size / 1024 / 1024).toFixed(2);
@@ -371,7 +391,7 @@ program.command("start", { isDefault: true }).description("Start the queue serve
371
391
  const verbose = options.verbose || false;
372
392
  ensureKanbanDir();
373
393
  await configureMcp();
374
- installSkills();
394
+ installSkills(true);
375
395
  const running = await isServerRunning(port);
376
396
  if (!running) {
377
397
  if (verbose) {
@@ -450,20 +470,64 @@ program.command("status").description("Check server status").option("-p, --port
450
470
  console.log("Server is not running");
451
471
  }
452
472
  });
453
- program.command("stop").description("Stop the background server").action(async () => {
454
- const pid = getRunningPid();
473
+ program.command("stop").description("Stop the server").option("-p, --port <port>", "Server port", DEFAULT_PORT.toString()).action(async (options) => {
474
+ const port = parseInt(options.port);
475
+ let pid = getRunningPid();
476
+ if (!pid) {
477
+ pid = findServerPidByPort(port);
478
+ }
455
479
  if (!pid) {
456
- console.log("No background server running");
480
+ console.log("No server running");
457
481
  return;
458
482
  }
459
483
  try {
460
484
  process.kill(pid, "SIGTERM");
461
485
  console.log(`Stopped server (PID: ${pid})`);
462
- clearPid();
486
+ await clearPid();
463
487
  } catch (error) {
464
488
  console.error(`Failed to stop server: ${error}`);
465
489
  }
466
490
  });
491
+ program.command("restart").description("Restart the server").option("-p, --port <port>", "Server port", DEFAULT_PORT.toString()).option("-d, --detach", "Run server in background").option("-v, --verbose", "Verbose output").action(async (options) => {
492
+ const port = parseInt(options.port);
493
+ const detach = options.detach || false;
494
+ const verbose = options.verbose || false;
495
+ let pid = getRunningPid();
496
+ if (!pid) {
497
+ pid = findServerPidByPort(port);
498
+ }
499
+ if (pid) {
500
+ console.log("Stopping server...");
501
+ try {
502
+ process.kill(pid, "SIGTERM");
503
+ await clearPid();
504
+ await new Promise((r) => setTimeout(r, 500));
505
+ } catch {
506
+ }
507
+ }
508
+ console.log("Starting server...");
509
+ ensureKanbanDir();
510
+ await configureMcp();
511
+ installSkills(true);
512
+ const child = await startServer(port, detach, verbose);
513
+ const serverReady = await waitForServer(port);
514
+ if (!serverReady) {
515
+ console.error("Server failed to start");
516
+ process.exit(1);
517
+ }
518
+ if (detach) {
519
+ console.log(`Server restarted on port ${port}`);
520
+ } else if (child) {
521
+ console.log(`Server running on port ${port}`);
522
+ console.log("Press Ctrl+C to stop");
523
+ process.on("SIGINT", () => {
524
+ child.kill();
525
+ process.exit(0);
526
+ });
527
+ await new Promise(() => {
528
+ });
529
+ }
530
+ });
467
531
  program.command("logs").description("View server logs").option("-f, --follow", "Follow log output").option("-n, --lines <lines>", "Number of lines to show", "50").action(async (options) => {
468
532
  if (!existsSync4(LOG_FILE)) {
469
533
  console.log("No logs found");
@@ -517,6 +581,33 @@ program.command("doctor").description("Check system configuration and diagnose c
517
581
  const fix = options.fix || false;
518
582
  await runDoctor(port, fix);
519
583
  });
584
+ program.command("upgrade").description("Upgrade claude-queue to the latest version").action(async () => {
585
+ console.log("\n\u{1F504} Upgrading claude-queue...\n");
586
+ const { execSync } = await import("child_process");
587
+ console.log("Updating npm package...");
588
+ try {
589
+ execSync("npm install -g claude-queue@latest", { stdio: "inherit" });
590
+ console.log("\u2713 Package updated\n");
591
+ } catch {
592
+ console.log("\u26A0\uFE0F Could not update globally, trying npx cache clear...");
593
+ try {
594
+ execSync("npx --yes clear-npx-cache 2>/dev/null || true", { stdio: "ignore" });
595
+ } catch {
596
+ }
597
+ }
598
+ console.log("Updating skill files...");
599
+ const skillUpdated = installSkills(true);
600
+ if (skillUpdated) {
601
+ console.log("\u2713 Skills updated\n");
602
+ } else {
603
+ console.log("\u26A0\uFE0F Could not update skills\n");
604
+ }
605
+ console.log("Updating MCP configuration...");
606
+ await configureMcp();
607
+ console.log("");
608
+ console.log("\u2705 Upgrade complete!");
609
+ console.log("\nRestart Claude Code to use the new version.");
610
+ });
520
611
  program.command("uninstall").description("Remove MCP server and skill from Claude Code configuration").option("--all", "Also remove all data (database, logs)").action(async (options) => {
521
612
  const fs = await import("fs/promises");
522
613
  const { join: join6 } = await import("path");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-queue",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "A local kanban board for managing Claude Code projects",
5
5
  "type": "module",
6
6
  "bin": {