@synkro-sh/cli 1.4.49 → 1.4.51

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
@@ -4291,7 +4291,7 @@ log "Starting local-CC session..."
4291
4291
  log "claude version: $(claude --version 2>&1 | head -1)"
4292
4292
 
4293
4293
  # Kill any previous session so restarts come up clean.
4294
- tmux kill-session -t "$SESSION" 2>/dev/null || true
4294
+ tmux kill-session -t "=$SESSION" 2>/dev/null || true
4295
4295
 
4296
4296
  # Start claude inside a detached tmux session so it has a real pty.
4297
4297
  # Redirect stderr to the log so we can see why it dies.
@@ -4302,7 +4302,7 @@ tmux new-session -d -s "$SESSION" \\
4302
4302
  # prompt: option 1 = "I am using this for local development" (accept),
4303
4303
  # option 2 = "Exit". Auto-accept by sending '1' + Enter.
4304
4304
  sleep 3
4305
- if tmux has-session -t "$SESSION" 2>/dev/null; then
4305
+ if tmux has-session -t "=$SESSION" 2>/dev/null; then
4306
4306
  tmux send-keys -t "$SESSION" '1' 2>/dev/null || true
4307
4307
  sleep 1
4308
4308
  tmux send-keys -t "$SESSION" Enter 2>/dev/null || true
@@ -4322,7 +4322,7 @@ fi
4322
4322
  log "tmux session started successfully."
4323
4323
 
4324
4324
  # Block on the tmux session so pueue's task lifetime tracks claude's.
4325
- while tmux has-session -t "$SESSION" 2>/dev/null; do
4325
+ while tmux has-session -t "=$SESSION" 2>/dev/null; do
4326
4326
  sleep 5
4327
4327
  done
4328
4328
 
@@ -4355,13 +4355,13 @@ fi
4355
4355
  log "Starting local-CC channel 2 (port ${CHANNEL_2_PORT})..."
4356
4356
  log "claude version: $(claude --version 2>&1 | head -1)"
4357
4357
 
4358
- tmux kill-session -t "$SESSION" 2>/dev/null || true
4358
+ tmux kill-session -t "=$SESSION" 2>/dev/null || true
4359
4359
 
4360
4360
  tmux new-session -d -s "$SESSION" \\
4361
4361
  "SYNKRO_CHANNEL_PORT=${CHANNEL_2_PORT} 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"
4362
4362
 
4363
4363
  sleep 3
4364
- if tmux has-session -t "$SESSION" 2>/dev/null; then
4364
+ if tmux has-session -t "=$SESSION" 2>/dev/null; then
4365
4365
  tmux send-keys -t "$SESSION" '1' 2>/dev/null || true
4366
4366
  sleep 1
4367
4367
  tmux send-keys -t "$SESSION" Enter 2>/dev/null || true
@@ -4378,7 +4378,7 @@ fi
4378
4378
 
4379
4379
  log "tmux session started successfully (port ${CHANNEL_2_PORT})."
4380
4380
 
4381
- while tmux has-session -t "$SESSION" 2>/dev/null; do
4381
+ while tmux has-session -t "=$SESSION" 2>/dev/null; do
4382
4382
  sleep 5
4383
4383
  done
4384
4384
 
@@ -4466,9 +4466,14 @@ function startTask(opts = {}) {
4466
4466
  const cwd = opts.cwd ?? ch.sessionDir;
4467
4467
  let existing = findTask(ch);
4468
4468
  while (existing) {
4469
- if (existing.status === "Running") {
4470
- spawnSync2("tmux", ["kill-session", "-t", ch.tmuxSession], { encoding: "utf-8" });
4469
+ if (existing.status === "Running" || existing.status === "Queued") {
4470
+ spawnSync2("tmux", ["kill-session", "-t", `=${ch.tmuxSession}`], { encoding: "utf-8" });
4471
4471
  spawnSync2("pueue", ["kill", String(existing.id)], { encoding: "utf-8" });
4472
+ for (let i = 0; i < 10; i++) {
4473
+ const check = findTask(ch);
4474
+ if (!check || check.id !== existing.id || check.status !== "Running" && check.status !== "Queued") break;
4475
+ spawnSync2("sleep", ["0.5"], { encoding: "utf-8" });
4476
+ }
4472
4477
  }
4473
4478
  spawnSync2("pueue", ["remove", String(existing.id)], { encoding: "utf-8" });
4474
4479
  existing = findTask(ch);
@@ -4495,11 +4500,20 @@ function startTask(opts = {}) {
4495
4500
  return created;
4496
4501
  }
4497
4502
  function stopTask(channel = CHANNEL_PRIMARY) {
4498
- spawnSync2("tmux", ["kill-session", "-t", channel.tmuxSession], { encoding: "utf-8" });
4499
- const t = findTask(channel);
4500
- if (!t) return;
4501
- spawnSync2("pueue", ["kill", String(t.id)], { encoding: "utf-8" });
4502
- spawnSync2("pueue", ["remove", String(t.id)], { encoding: "utf-8" });
4503
+ spawnSync2("tmux", ["kill-session", "-t", `=${channel.tmuxSession}`], { encoding: "utf-8" });
4504
+ let t = findTask(channel);
4505
+ while (t) {
4506
+ if (t.status === "Running" || t.status === "Queued") {
4507
+ spawnSync2("pueue", ["kill", String(t.id)], { encoding: "utf-8" });
4508
+ for (let i = 0; i < 10; i++) {
4509
+ const check = findTask(channel);
4510
+ if (!check || check.id !== t.id || check.status !== "Running" && check.status !== "Queued") break;
4511
+ spawnSync2("sleep", ["0.5"], { encoding: "utf-8" });
4512
+ }
4513
+ }
4514
+ spawnSync2("pueue", ["remove", String(t.id)], { encoding: "utf-8" });
4515
+ t = findTask(channel);
4516
+ }
4503
4517
  }
4504
4518
  function tailLogs(lines = 80, channel = CHANNEL_PRIMARY) {
4505
4519
  const t = findTask(channel);
@@ -5035,7 +5049,7 @@ function writeConfigEnv(opts) {
5035
5049
  `SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
5036
5050
  `SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
5037
5051
  `SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
5038
- `SYNKRO_VERSION=${shellQuoteSingle("1.4.49")}`
5052
+ `SYNKRO_VERSION=${shellQuoteSingle("1.4.51")}`
5039
5053
  ];
5040
5054
  if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle(safeSynkroBin)}`);
5041
5055
  if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
@@ -5247,14 +5261,16 @@ async function installCommand(opts = {}) {
5247
5261
  if (token2) {
5248
5262
  const profile2 = await fetchUserProfile(gatewayUrl, token2);
5249
5263
  if (profile2.localInference && !isLocalCCEnabled()) {
5250
- console.log("Local inference enabled in your profile \u2014 setting up local-CC channel...");
5264
+ console.log("Local inference enabled \u2014 setting up local-CC channels...");
5251
5265
  try {
5252
5266
  assertClaudeInstalled();
5253
5267
  assertPueueInstalled();
5254
5268
  assertTmuxInstalled();
5269
+ stopTask();
5270
+ stopTask(CHANNEL_SECONDARY);
5255
5271
  installLocalCC();
5256
- const t1 = ensureRunning();
5257
- const t2 = ensureRunning({ channel: CHANNEL_SECONDARY });
5272
+ const t1 = startTask();
5273
+ const t2 = startTask({ channel: CHANNEL_SECONDARY });
5258
5274
  console.log(` channel 1: pueue id=${t1.id} channel 2: pueue id=${t2.id}`);
5259
5275
  console.log(" Waiting for both channels...");
5260
5276
  const [ready1, ready2] = await Promise.all([
@@ -5432,6 +5448,14 @@ async function installCommand(opts = {}) {
5432
5448
  } catch {
5433
5449
  }
5434
5450
  const profile = await fetchUserProfile(gatewayUrl, token);
5451
+ const priorLocalFlag = (() => {
5452
+ try {
5453
+ const content = readFileSync10(CONFIG_PATH3, "utf-8");
5454
+ return content.includes("SYNKRO_LOCAL_INFERENCE='yes'");
5455
+ } catch {
5456
+ return false;
5457
+ }
5458
+ })();
5435
5459
  const synkroBundle = resolveSynkroBundle();
5436
5460
  writeConfigEnv({ gatewayUrl, userId, orgId, email, tier: profile.tier, inference: profile.inference, synkroBin: synkroBundle, transcriptConsent, localInference: profile.localInference });
5437
5461
  console.log(`Wrote config to ${CONFIG_PATH3}`);
@@ -5472,15 +5496,7 @@ async function installCommand(opts = {}) {
5472
5496
  console.warn(` \u26A0 Some dependencies missing \u2014 \`synkro local-cc enable\` may not work until they're installed.`);
5473
5497
  }
5474
5498
  console.log();
5475
- const priorLocalFlag = (() => {
5476
- try {
5477
- const content = readFileSync10(CONFIG_PATH3, "utf-8");
5478
- return content.includes("SYNKRO_LOCAL_INFERENCE='yes'");
5479
- } catch {
5480
- return false;
5481
- }
5482
- })();
5483
- if (profile.localInference || priorLocalFlag && localCcDeps.length === 3) {
5499
+ if (profile.localInference && localCcDeps.length === 3) {
5484
5500
  try {
5485
5501
  stopTask();
5486
5502
  stopTask(CHANNEL_SECONDARY);
@@ -7169,7 +7185,7 @@ async function cmdStatus() {
7169
7185
  }
7170
7186
  const ch1Up = await isChannelAvailable();
7171
7187
  console.log(`Channel 1 ${CHANNEL_HOST}:${CHANNEL_PORT}: ${ch1Up ? "reachable" : "unreachable"}`);
7172
- const tmux1 = spawnSync4("tmux", ["has-session", "-t", TMUX_SESSION_NAME], { encoding: "utf-8" });
7188
+ const tmux1 = spawnSync4("tmux", ["has-session", "-t", `=${TMUX_SESSION_NAME}`], { encoding: "utf-8" });
7173
7189
  console.log(`tmux '${TMUX_SESSION_NAME}': ${tmux1.status === 0 ? "live" : "absent"}`);
7174
7190
  const t2 = findTask(CHANNEL_SECONDARY);
7175
7191
  if (!t2) {
@@ -7179,7 +7195,7 @@ async function cmdStatus() {
7179
7195
  }
7180
7196
  const ch2Up = await isChannelAvailable(CHANNEL_2_PORT);
7181
7197
  console.log(`Channel 2 ${CHANNEL_HOST}:${CHANNEL_2_PORT}: ${ch2Up ? "reachable" : "unreachable"}`);
7182
- const tmux2 = spawnSync4("tmux", ["has-session", "-t", TMUX_SESSION_NAME_2], { encoding: "utf-8" });
7198
+ const tmux2 = spawnSync4("tmux", ["has-session", "-t", `=${TMUX_SESSION_NAME_2}`], { encoding: "utf-8" });
7183
7199
  console.log(`tmux '${TMUX_SESSION_NAME_2}': ${tmux2.status === 0 ? "live" : "absent"}`);
7184
7200
  }
7185
7201
  async function cmdEnable() {
@@ -7371,7 +7387,7 @@ function cmdLogs(rest) {
7371
7387
  function cmdAttach(rest) {
7372
7388
  assertTmuxInstalled();
7373
7389
  const readonly = rest.some((a) => a === "--readonly" || a === "-r");
7374
- const has = spawnSync4("tmux", ["has-session", "-t", TMUX_SESSION_NAME], { encoding: "utf-8" });
7390
+ const has = spawnSync4("tmux", ["has-session", "-t", `=${TMUX_SESSION_NAME}`], { encoding: "utf-8" });
7375
7391
  if (has.status !== 0) {
7376
7392
  console.error(`No tmux session '${TMUX_SESSION_NAME}' running. Start it with: synkro local-cc start`);
7377
7393
  process.exit(1);