claude-tmux 1.0.1 → 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/index.js +8 -40
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
3
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
4
  import { z } from "zod";
5
5
  import { execSync } from "child_process";
6
- import { writeFileSync, appendFileSync } from "fs";
6
+ import { writeFileSync } from "fs";
7
7
  const SESSION_PREFIX = "claude-";
8
8
  function runTmux(args) {
9
9
  return execSync(`tmux ${args}`, { encoding: "utf-8", timeout: 10000 }).trim();
@@ -22,7 +22,7 @@ function sessionName(name) {
22
22
  function sleep(ms) {
23
23
  return new Promise(resolve => setTimeout(resolve, ms));
24
24
  }
25
- function isClaudeIdle(output) {
25
+ function isBusy(output) {
26
26
  // Claude shows these patterns when actively working
27
27
  const busyPatterns = [
28
28
  'ctrl+c to interrupt',
@@ -30,11 +30,10 @@ function isClaudeIdle(output) {
30
30
  ];
31
31
  for (const pattern of busyPatterns) {
32
32
  if (output.includes(pattern)) {
33
- return false;
33
+ return true;
34
34
  }
35
35
  }
36
- // Not clearly busy - considered idle
37
- return true;
36
+ return false;
38
37
  }
39
38
  function filterUIChrome(output) {
40
39
  const lines = output.split('\n');
@@ -54,55 +53,24 @@ function filterUIChrome(output) {
54
53
  });
55
54
  return filtered.join('\n').trim();
56
55
  }
57
- function isClearlBusy(output) {
58
- // These patterns definitively mean Claude is still working
59
- const definitelyBusy = [
60
- 'ctrl+c to interrupt',
61
- 'esc to interrupt',
62
- ];
63
- for (const pattern of definitelyBusy) {
64
- if (output.includes(pattern)) {
65
- return true;
66
- }
67
- }
68
- return false;
69
- }
70
56
  async function waitForIdle(session) {
71
57
  const timeout = 600000; // 10 minutes
72
58
  const lines = 50;
73
59
  const startTime = Date.now();
74
60
  let lastOutput = "";
75
61
  let stableCount = 0;
76
- let iterations = 0;
77
62
  while (Date.now() - startTime < timeout) {
78
63
  await sleep(2000);
79
- iterations++;
80
64
  try {
81
65
  const output = runTmux(`capture-pane -t "${session}" -p -S -${lines}`);
82
- const busy = isClearlBusy(output);
83
- // Debug: write to file so we can see what's happening
84
- appendFileSync('/tmp/claude-tmux-debug.log', `[${new Date().toISOString()}] iteration=${iterations} busy=${busy} outputLen=${output.length}\n`);
85
- // If clearly busy, never return early
86
- if (isClearlBusy(output)) {
66
+ // If busy, keep waiting
67
+ if (isBusy(output)) {
87
68
  lastOutput = output;
88
69
  stableCount = 0;
89
70
  continue;
90
71
  }
91
- // If idle, return
92
- if (isClaudeIdle(output)) {
93
- return filterUIChrome(output);
94
- }
95
- // Fallback: if output is stable for 6 seconds and not clearly busy, return
96
- if (output === lastOutput) {
97
- stableCount++;
98
- if (stableCount >= 3) {
99
- return filterUIChrome(output);
100
- }
101
- }
102
- else {
103
- stableCount = 0;
104
- lastOutput = output;
105
- }
72
+ // Not busy - return
73
+ return filterUIChrome(output);
106
74
  }
107
75
  catch (e) {
108
76
  return `Error: ${e.message}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-tmux",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "MCP server for orchestrating multiple Claude Code instances via tmux",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",