@synkro-sh/cli 1.4.29 → 1.4.31

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.
package/dist/bootstrap.js CHANGED
@@ -3047,23 +3047,54 @@ var init_install = __esm({
3047
3047
  set -uo pipefail
3048
3048
 
3049
3049
  SESSION=${TMUX_SESSION_NAME}
3050
+ LOG="$HOME/.synkro/cc_sessions/run-claude.log"
3051
+
3052
+ log() { echo "[$(date '+%H:%M:%S')] $*" >> "$LOG"; echo "$*"; }
3053
+
3054
+ # Pre-flight checks
3055
+ if ! command -v claude >/dev/null 2>&1; then
3056
+ log "ERROR: claude CLI not found on PATH. Install Claude Code first."
3057
+ exit 1
3058
+ fi
3059
+
3060
+ if ! command -v tmux >/dev/null 2>&1; then
3061
+ log "ERROR: tmux not found on PATH."
3062
+ exit 1
3063
+ fi
3064
+
3065
+ # Check claude is authenticated
3066
+ if ! claude --version >/dev/null 2>&1; then
3067
+ log "ERROR: claude --version failed. Is Claude Code installed correctly?"
3068
+ exit 1
3069
+ fi
3070
+
3071
+ log "Starting local-CC session..."
3072
+ log "claude version: $(claude --version 2>&1 | head -1)"
3050
3073
 
3051
3074
  # Kill any previous session so restarts come up clean.
3052
3075
  tmux kill-session -t "$SESSION" 2>/dev/null || true
3053
3076
 
3054
3077
  # Start claude inside a detached tmux session so it has a real pty.
3055
- #
3056
- # --setting-sources project,local: skip ~/.claude/settings.json so the
3057
- # synkro PreToolUse/PostToolUse hooks installed there don't load. Without
3058
- # this, the grader's own tool calls would re-trigger synkro grading,
3059
- # causing recursion / deadlock with the same channel session.
3078
+ # Redirect stderr to the log so we can see why it dies.
3060
3079
  tmux new-session -d -s "$SESSION" \\
3061
- "claude --dangerously-load-development-channels server:synkro-local --dangerously-skip-permissions --setting-sources project,local --model claude-sonnet-4-6"
3080
+ "claude --dangerously-load-development-channels server:synkro-local --dangerously-skip-permissions --setting-sources project,local --model claude-sonnet-4-6 2>>$LOG; echo 'claude exited with code '$'?' >> $LOG"
3081
+
3082
+ # Give claude a moment to start before checking
3083
+ sleep 2
3084
+ if ! tmux has-session -t "$SESSION" 2>/dev/null; then
3085
+ log "ERROR: tmux session died immediately. Check $LOG for details."
3086
+ log "Try running claude manually to verify auth: claude --print 'say ok'"
3087
+ exit 1
3088
+ fi
3089
+
3090
+ log "tmux session started successfully."
3062
3091
 
3063
3092
  # Block on the tmux session so pueue's task lifetime tracks claude's.
3064
3093
  while tmux has-session -t "$SESSION" 2>/dev/null; do
3065
3094
  sleep 5
3066
3095
  done
3096
+
3097
+ log "tmux session ended."
3067
3098
  `;
3068
3099
  MCP_SERVER_NAME = "synkro-local";
3069
3100
  PLUGIN_PACKAGE_JSON = JSON.stringify(
@@ -3686,7 +3717,7 @@ function writeConfigEnv(opts) {
3686
3717
  `SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
3687
3718
  `SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
3688
3719
  `SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
3689
- `SYNKRO_VERSION=${shellQuoteSingle("1.4.29")}`
3720
+ `SYNKRO_VERSION=${shellQuoteSingle("1.4.31")}`
3690
3721
  ];
3691
3722
  if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle(safeSynkroBin)}`);
3692
3723
  if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
@@ -4089,7 +4120,7 @@ async function installCommand(opts = {}) {
4089
4120
  console.log(`Installed local-CC channel plugin at ${r.pluginPath}`);
4090
4121
  const t = ensureRunning();
4091
4122
  console.log(`Local-CC pueue task: id=${t.id} status=${t.status}`);
4092
- console.log("Waiting for channel...");
4123
+ console.log("Waiting for channel (up to 60s)...");
4093
4124
  const ready = await waitForChannelReady(CHANNEL_PORT, 6e4, CHANNEL_HOST);
4094
4125
  if (ready) {
4095
4126
  console.log(` channel ready at ${CHANNEL_HOST}:${CHANNEL_PORT}`);
@@ -4101,7 +4132,35 @@ async function installCommand(opts = {}) {
4101
4132
  console.log(" warmup skipped (non-fatal)\n");
4102
4133
  }
4103
4134
  } else {
4104
- console.warn(` \u26A0 channel did not come up within 60s \u2014 check \`synkro local-cc logs\`
4135
+ console.warn(` \u26A0 Channel did not come up within 60s.`);
4136
+ try {
4137
+ const { spawnSync: sp } = await import("child_process");
4138
+ const tmuxCheck = sp("tmux", ["has-session", "-t", "synkro-local-cc"], { encoding: "utf-8" });
4139
+ console.warn(` tmux session: ${tmuxCheck.status === 0 ? "running" : "not running"}`);
4140
+ const pueueTask = findTask();
4141
+ console.warn(` pueue task: ${pueueTask ? `id=${pueueTask.id} status=${pueueTask.status}` : "not found"}`);
4142
+ const bunCheck = sp("bun", ["--version"], { encoding: "utf-8" });
4143
+ console.warn(` bun: ${bunCheck.status === 0 ? bunCheck.stdout.trim() : "not found"}`);
4144
+ const claudeCheck = sp("claude", ["--version"], { encoding: "utf-8" });
4145
+ console.warn(` claude: ${claudeCheck.status === 0 ? claudeCheck.stdout.trim().split("\n")[0] : "not found"}`);
4146
+ if (pueueTask) {
4147
+ const logs = tailLogs(15);
4148
+ if (logs && logs !== "(no output)") {
4149
+ console.warn(` pueue logs (last 15 lines):`);
4150
+ for (const line of logs.split("\n").slice(0, 15)) {
4151
+ console.warn(` ${line}`);
4152
+ }
4153
+ }
4154
+ }
4155
+ const logPath = join11(homedir10(), ".synkro", "cc_sessions", "run-claude.log");
4156
+ if (existsSync11(logPath)) {
4157
+ const logContent = readFileSync10(logPath, "utf-8").trim().split("\n").slice(-10);
4158
+ console.warn(` run-claude.log:`);
4159
+ for (const line of logContent) console.warn(` ${line}`);
4160
+ }
4161
+ } catch {
4162
+ }
4163
+ console.warn(` Run \`synkro local-cc status\` and \`synkro local-cc logs --tmux\` to debug.
4105
4164
  `);
4106
4165
  }
4107
4166
  } catch (err) {