claude-queue 1.0.0 → 1.0.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 (2) hide show
  1. package/dist/cli.js +113 -11
  2. package/package.json +2 -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());
@@ -99,8 +118,19 @@ async function startServer(port, detach, verbose) {
99
118
  }
100
119
  const child = spawn("node", [serverPath], {
101
120
  env,
102
- stdio: verbose ? "inherit" : "pipe"
121
+ stdio: verbose ? "inherit" : ["ignore", "pipe", "pipe"]
103
122
  });
123
+ if (!verbose && child.stderr) {
124
+ let stderrOutput = "";
125
+ child.stderr.on("data", (data) => {
126
+ stderrOutput += data.toString();
127
+ });
128
+ child.on("exit", (code) => {
129
+ if (code !== 0 && stderrOutput) {
130
+ console.error("Server error:", stderrOutput.trim());
131
+ }
132
+ });
133
+ }
104
134
  return child;
105
135
  }
106
136
  async function waitForServer(port, maxWait = 1e4) {
@@ -193,11 +223,11 @@ function getSkillPath() {
193
223
  }
194
224
  throw new Error("Skill file not found. Run 'pnpm build' first.");
195
225
  }
196
- function installSkills() {
226
+ function installSkills(force = false) {
197
227
  const queueSkillDir = join3(SKILLS_DIR, "queue");
198
228
  const queueSkillFile = join3(queueSkillDir, "SKILL.md");
199
- if (existsSync2(queueSkillFile)) {
200
- return;
229
+ if (existsSync2(queueSkillFile) && !force) {
230
+ return false;
201
231
  }
202
232
  if (!existsSync2(SKILLS_DIR)) {
203
233
  mkdirSync2(SKILLS_DIR, { recursive: true });
@@ -209,6 +239,7 @@ function installSkills() {
209
239
  const skillContent = readFileSync2(skillSourcePath, "utf-8");
210
240
  writeFileSync2(queueSkillFile, skillContent);
211
241
  console.log("\u2713 Installed /queue skill to ~/.claude/skills/queue/");
242
+ return true;
212
243
  }
213
244
  function removeMcp() {
214
245
  const settingsPath = join3(CLAUDE_DIR, "settings.json");
@@ -287,7 +318,7 @@ async function runDoctor(port, fix) {
287
318
  console.log(" \u2192 Created settings.json with MCP config");
288
319
  }
289
320
  }
290
- const skillPath = join4(SKILLS_DIR, "kanban", "SKILL.md");
321
+ const skillPath = join4(SKILLS_DIR, "queue", "SKILL.md");
291
322
  if (existsSync3(skillPath)) {
292
323
  console.log("\u2705 /queue skill installed");
293
324
  } else {
@@ -304,7 +335,7 @@ async function runDoctor(port, fix) {
304
335
  console.log("\u26A0\uFE0F Queue data directory not created yet");
305
336
  warnings++;
306
337
  }
307
- const dbPath = join4(KANBAN_DIR, "kanban.db");
338
+ const dbPath = join4(KANBAN_DIR, "queue.db");
308
339
  if (existsSync3(dbPath)) {
309
340
  const stats = await import("fs/promises").then((fs) => fs.stat(dbPath));
310
341
  const sizeMB = (stats.size / 1024 / 1024).toFixed(2);
@@ -371,7 +402,7 @@ program.command("start", { isDefault: true }).description("Start the queue serve
371
402
  const verbose = options.verbose || false;
372
403
  ensureKanbanDir();
373
404
  await configureMcp();
374
- installSkills();
405
+ installSkills(true);
375
406
  const running = await isServerRunning(port);
376
407
  if (!running) {
377
408
  if (verbose) {
@@ -450,20 +481,64 @@ program.command("status").description("Check server status").option("-p, --port
450
481
  console.log("Server is not running");
451
482
  }
452
483
  });
453
- program.command("stop").description("Stop the background server").action(async () => {
454
- const pid = getRunningPid();
484
+ program.command("stop").description("Stop the server").option("-p, --port <port>", "Server port", DEFAULT_PORT.toString()).action(async (options) => {
485
+ const port = parseInt(options.port);
486
+ let pid = getRunningPid();
455
487
  if (!pid) {
456
- console.log("No background server running");
488
+ pid = findServerPidByPort(port);
489
+ }
490
+ if (!pid) {
491
+ console.log("No server running");
457
492
  return;
458
493
  }
459
494
  try {
460
495
  process.kill(pid, "SIGTERM");
461
496
  console.log(`Stopped server (PID: ${pid})`);
462
- clearPid();
497
+ await clearPid();
463
498
  } catch (error) {
464
499
  console.error(`Failed to stop server: ${error}`);
465
500
  }
466
501
  });
502
+ 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) => {
503
+ const port = parseInt(options.port);
504
+ const detach = options.detach || false;
505
+ const verbose = options.verbose || false;
506
+ let pid = getRunningPid();
507
+ if (!pid) {
508
+ pid = findServerPidByPort(port);
509
+ }
510
+ if (pid) {
511
+ console.log("Stopping server...");
512
+ try {
513
+ process.kill(pid, "SIGTERM");
514
+ await clearPid();
515
+ await new Promise((r) => setTimeout(r, 500));
516
+ } catch {
517
+ }
518
+ }
519
+ console.log("Starting server...");
520
+ ensureKanbanDir();
521
+ await configureMcp();
522
+ installSkills(true);
523
+ const child = await startServer(port, detach, verbose);
524
+ const serverReady = await waitForServer(port);
525
+ if (!serverReady) {
526
+ console.error("Server failed to start");
527
+ process.exit(1);
528
+ }
529
+ if (detach) {
530
+ console.log(`Server restarted on port ${port}`);
531
+ } else if (child) {
532
+ console.log(`Server running on port ${port}`);
533
+ console.log("Press Ctrl+C to stop");
534
+ process.on("SIGINT", () => {
535
+ child.kill();
536
+ process.exit(0);
537
+ });
538
+ await new Promise(() => {
539
+ });
540
+ }
541
+ });
467
542
  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
543
  if (!existsSync4(LOG_FILE)) {
469
544
  console.log("No logs found");
@@ -517,6 +592,33 @@ program.command("doctor").description("Check system configuration and diagnose c
517
592
  const fix = options.fix || false;
518
593
  await runDoctor(port, fix);
519
594
  });
595
+ program.command("upgrade").description("Upgrade claude-queue to the latest version").action(async () => {
596
+ console.log("\n\u{1F504} Upgrading claude-queue...\n");
597
+ const { execSync } = await import("child_process");
598
+ console.log("Updating npm package...");
599
+ try {
600
+ execSync("npm install -g claude-queue@latest", { stdio: "inherit" });
601
+ console.log("\u2713 Package updated\n");
602
+ } catch {
603
+ console.log("\u26A0\uFE0F Could not update globally, trying npx cache clear...");
604
+ try {
605
+ execSync("npx --yes clear-npx-cache 2>/dev/null || true", { stdio: "ignore" });
606
+ } catch {
607
+ }
608
+ }
609
+ console.log("Updating skill files...");
610
+ const skillUpdated = installSkills(true);
611
+ if (skillUpdated) {
612
+ console.log("\u2713 Skills updated\n");
613
+ } else {
614
+ console.log("\u26A0\uFE0F Could not update skills\n");
615
+ }
616
+ console.log("Updating MCP configuration...");
617
+ await configureMcp();
618
+ console.log("");
619
+ console.log("\u2705 Upgrade complete!");
620
+ console.log("\nRestart Claude Code to use the new version.");
621
+ });
520
622
  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
623
  const fs = await import("fs/promises");
522
624
  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.3",
4
4
  "description": "A local kanban board for managing Claude Code projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -48,6 +48,7 @@
48
48
  "commander": "^14.0.2",
49
49
  "cors": "^2.8.5",
50
50
  "express": "^5.2.1",
51
+ "http-proxy-middleware": "^3.0.5",
51
52
  "nanoid": "^5.1.6"
52
53
  },
53
54
  "devDependencies": {