@synkro-sh/cli 1.4.89 → 1.4.90

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
@@ -508,7 +508,7 @@ function installCursorMcpConfig(opts) {
508
508
  if (entry?.[SYNKRO_MARKER3] === true) delete config.mcpServers[name];
509
509
  }
510
510
  if (opts.local) {
511
- const port = process.env.SYNKRO_MCP_PORT || "8931";
511
+ const port = process.env.SYNKRO_MCP_PORT || "18931";
512
512
  const url2 = `http://127.0.0.1:${port}/`;
513
513
  const jwtPath = join2(homedir3(), ".synkro", ".mcp-jwt");
514
514
  let jwt2 = "";
@@ -986,7 +986,7 @@ export function detectRepo(cwd: string, transcriptPath?: string): string {
986
986
 
987
987
  // \u2500\u2500\u2500 Channel Health \u2500\u2500\u2500
988
988
 
989
- export async function channelUp(port = 8929): Promise<boolean> {
989
+ export async function channelUp(port = 18929): Promise<boolean> {
990
990
  return new Promise(resolve => {
991
991
  const sock = require('node:net').connect(port, '127.0.0.1');
992
992
  const done = (ok: boolean) => { try { sock.destroy(); } catch {} resolve(ok); };
@@ -997,7 +997,7 @@ export async function channelUp(port = 8929): Promise<boolean> {
997
997
  }
998
998
 
999
999
  export async function cweChannelUp(): Promise<boolean> {
1000
- return channelUp(8930);
1000
+ return channelUp(18930);
1001
1001
  }
1002
1002
 
1003
1003
  // \u2500\u2500\u2500 Config Loading \u2500\u2500\u2500
@@ -1030,7 +1030,7 @@ export async function loadConfig(jwt: string, query?: string): Promise<HookConfi
1030
1030
  };
1031
1031
 
1032
1032
  // Local-first: fetch from the local MCP server (PGLite-backed) \u2014 zero network egress.
1033
- const mcpPort = process.env.SYNKRO_MCP_PORT || '8931';
1033
+ const mcpPort = process.env.SYNKRO_MCP_PORT || '18931';
1034
1034
  try {
1035
1035
  const resp = await fetch('http://127.0.0.1:' + mcpPort + '/api/local/hook-config', {
1036
1036
  signal: AbortSignal.timeout(1500),
@@ -1146,13 +1146,13 @@ export async function localGrade(surface: string, prompt: string, timeoutMs = 20
1146
1146
  if (!(await channelUp())) throw new Error('SYNKRO_CHANNEL_DOWN');
1147
1147
  const jwt = loadJwt();
1148
1148
  if (!jwt) throw new Error('NO_JWT');
1149
- return channelGrade(ROLE_MAP[surface] || 'grade-edit', prompt, jwt, 8929, timeoutMs);
1149
+ return channelGrade(ROLE_MAP[surface] || 'grade-edit', prompt, jwt, 18929, timeoutMs);
1150
1150
  }
1151
1151
 
1152
1152
  export async function localGradeCwe(prompt: string): Promise<string> {
1153
1153
  const jwt = loadJwt();
1154
1154
  if (!jwt) throw new Error('NO_JWT');
1155
- return channelGrade('grade-cwe', prompt, jwt, 8930, 45000);
1155
+ return channelGrade('grade-cwe', prompt, jwt, 18930, 45000);
1156
1156
  }
1157
1157
 
1158
1158
  // \u2500\u2500\u2500 Session Action Log \u2500\u2500\u2500
@@ -1273,6 +1273,13 @@ export function parseVerdict(resp: string): Verdict {
1273
1273
  const okMatch = inner.match(/<ok>(.*?)<\\/ok>/);
1274
1274
  if (okMatch) verdict.ok = okMatch[1].trim() !== 'false';
1275
1275
 
1276
+ const decisionMatch = inner.match(/<decision>(.*?)<\\/decision>/);
1277
+ if (decisionMatch) {
1278
+ const d = decisionMatch[1].trim().toLowerCase();
1279
+ if (d === 'block' || d === 'deny' || d === 'fail') verdict.ok = false;
1280
+ else if (d === 'allow' || d === 'pass' || d === 'approve') verdict.ok = true;
1281
+ }
1282
+
1276
1283
  const reasonMatch = inner.match(/<reason>(.*?)<\\/reason>/) || inner.match(/<reasoning>(.*?)<\\/reasoning>/);
1277
1284
  if (reasonMatch) verdict.reason = reasonMatch[1].trim();
1278
1285
 
@@ -1401,7 +1408,7 @@ export function dispatchCapture(
1401
1408
 
1402
1409
  export function appendLocalTelemetry(body: Record<string, any>): void {
1403
1410
  const event = { ...body, _ts: new Date().toISOString() };
1404
- const mcpPort = process.env.SYNKRO_MCP_PORT || '8931';
1411
+ const mcpPort = process.env.SYNKRO_MCP_PORT || '18931';
1405
1412
  let mcpToken = '';
1406
1413
  try { mcpToken = readFileSync(join(HOME, '.synkro', '.mcp-jwt'), 'utf-8').trim(); } catch {}
1407
1414
  if (!mcpToken) return;
@@ -1992,7 +1999,7 @@ async function main() {
1992
1999
  }
1993
2000
 
1994
2001
  if (rt === 'local') {
1995
- // \u2500\u2500\u2500 Local grading: org rules ONLY (channel 1, port 8929) \u2500\u2500\u2500
2002
+ // \u2500\u2500\u2500 Local grading: org rules ONLY (channel 1, port 18929) \u2500\u2500\u2500
1996
2003
  const proposedShort = proposed.slice(0, 4000);
1997
2004
  const sessionLog = compressSessionLog(readSessionLog(sessionId));
1998
2005
  const graderPrompt = [
@@ -3481,7 +3488,7 @@ async function main() {
3481
3488
 
3482
3489
  const fakeConfig: HookConfig = { captureDepth: 'local_only', tier: 'standard', silent, policyName, rules: [] };
3483
3490
  const tagStr = tag(rt, fakeConfig);
3484
- const routeLine = tagStr + ' inference: ' + (isChannelUp ? 'local-cc (channel reachable on 127.0.0.1:8929)' : 'cloud (local-cc channel not reachable)');
3491
+ const routeLine = tagStr + ' inference: ' + (isChannelUp ? 'local-cc (channel reachable on 127.0.0.1:18929)' : 'cloud (local-cc channel not reachable)');
3485
3492
 
3486
3493
  if (!jwt) {
3487
3494
  outputJson({ systemMessage: routeLine });
@@ -5444,6 +5451,10 @@ async function dockerInstall(opts = {}) {
5444
5451
  `${MCP_JWT_PATH}:/data/.mcp-jwt:ro`,
5445
5452
  "-v",
5446
5453
  `${credsDir}:/home/synkro/.claude:rw`,
5454
+ "-v",
5455
+ `${join7(homedir7(), ".claude")}:/data/claude-host:ro`,
5456
+ "-v",
5457
+ `${join7(homedir7(), ".claude.json")}:/home/synkro/.claude.json:rw`,
5447
5458
  "-e",
5448
5459
  `WORKERS_PER_POOL=${workers}`,
5449
5460
  image
@@ -5658,7 +5669,7 @@ function writeConfigEnv(opts) {
5658
5669
  `SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
5659
5670
  `SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
5660
5671
  `SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
5661
- `SYNKRO_VERSION=${shellQuoteSingle("1.4.89")}`
5672
+ `SYNKRO_VERSION=${shellQuoteSingle("1.4.90")}`
5662
5673
  ];
5663
5674
  if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle(safeSynkroBin)}`);
5664
5675
  if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
@@ -6373,7 +6384,7 @@ import { createInterface } from 'node:readline';
6373
6384
 
6374
6385
  const HOME = homedir();
6375
6386
  const TOKEN_PATH = join(HOME, '.synkro', '.mcp-jwt');
6376
- const PORT = parseInt(process.env.SYNKRO_MCP_PORT || '8931', 10);
6387
+ const PORT = parseInt(process.env.SYNKRO_MCP_PORT || '18931', 10);
6377
6388
  const URL = \`http://127.0.0.1:\${PORT}\`;
6378
6389
 
6379
6390
  let token = '';
@@ -6415,105 +6426,6 @@ rl.on('line', async (line) => {
6415
6426
  }
6416
6427
  });
6417
6428
 
6418
- // cli/local-cc/pueue.ts
6419
- import { execFileSync, spawnSync as spawnSync3, spawn } from "child_process";
6420
- import { homedir as homedir9 } from "os";
6421
- import { join as join9 } from "path";
6422
- import { connect } from "net";
6423
- function pueueAvailable() {
6424
- const r = spawnSync3("pueue", ["--version"], { encoding: "utf-8" });
6425
- if (r.status !== 0) {
6426
- throw new PueueError("pueue CLI not found on PATH. Install pueue (https://github.com/Nukesor/pueue) and start `pueued`.");
6427
- }
6428
- }
6429
- function statusJson() {
6430
- pueueAvailable();
6431
- const r = spawnSync3("pueue", ["status", "--json"], { encoding: "utf-8" });
6432
- if (r.status !== 0) {
6433
- throw new PueueError(`pueue status failed: ${r.stderr || r.stdout || "unknown error"} \u2014 is pueued running?`);
6434
- }
6435
- try {
6436
- return JSON.parse(r.stdout);
6437
- } catch (err) {
6438
- throw new PueueError(`pueue status returned non-JSON output: ${r.stdout.slice(0, 200)}`, err);
6439
- }
6440
- }
6441
- function statusName(s) {
6442
- if (typeof s === "string") return s;
6443
- if (s && typeof s === "object") {
6444
- if ("Running" in s) return "Running";
6445
- if ("Done" in s) {
6446
- const result = s.Done?.result;
6447
- if (typeof result === "string") return `Done (${result})`;
6448
- if (result && typeof result === "object") return `Done (${Object.keys(result)[0] ?? "unknown"})`;
6449
- return "Done";
6450
- }
6451
- return Object.keys(s)[0] ?? "unknown";
6452
- }
6453
- return "unknown";
6454
- }
6455
- function findTask(channel = CHANNEL_PRIMARY) {
6456
- const data = statusJson();
6457
- for (const [id, t] of Object.entries(data.tasks)) {
6458
- if (t.label === channel.taskLabel) {
6459
- return {
6460
- id: Number(id),
6461
- label: t.label,
6462
- status: statusName(t.status),
6463
- command: t.command,
6464
- cwd: t.path
6465
- };
6466
- }
6467
- }
6468
- return null;
6469
- }
6470
- function stopTask(channel = CHANNEL_PRIMARY) {
6471
- spawnSync3("tmux", ["kill-session", "-t", `=${channel.tmuxSession}`], { encoding: "utf-8" });
6472
- let t = findTask(channel);
6473
- while (t) {
6474
- if (t.status === "Running" || t.status === "Queued") {
6475
- spawnSync3("pueue", ["kill", String(t.id)], { encoding: "utf-8" });
6476
- for (let i = 0; i < 10; i++) {
6477
- const check = findTask(channel);
6478
- if (!check || check.id !== t.id || check.status !== "Running" && check.status !== "Queued") break;
6479
- spawnSync3("sleep", ["0.5"], { encoding: "utf-8" });
6480
- }
6481
- }
6482
- spawnSync3("pueue", ["remove", String(t.id)], { encoding: "utf-8" });
6483
- t = findTask(channel);
6484
- }
6485
- }
6486
- var TASK_LABEL, TMUX_SESSION, SESSION_DIR, TASK_LABEL_2, TMUX_SESSION_2, SESSION_DIR_2, TASK_LABEL_3, TMUX_SESSION_3, SESSION_DIR_3, TASK_LABEL_4, TMUX_SESSION_4, SESSION_DIR_4, PueueError, CHANNEL_PRIMARY, CHANNEL_SECONDARY, CHANNEL_TERTIARY, CHANNEL_QUATERNARY;
6487
- var init_pueue = __esm({
6488
- "cli/local-cc/pueue.ts"() {
6489
- "use strict";
6490
- TASK_LABEL = "synkro-local-cc";
6491
- TMUX_SESSION = "synkro-local-cc";
6492
- SESSION_DIR = join9(homedir9(), ".synkro", "cc_sessions");
6493
- TASK_LABEL_2 = "synkro-local-cc-2";
6494
- TMUX_SESSION_2 = "synkro-local-cc-2";
6495
- SESSION_DIR_2 = join9(homedir9(), ".synkro", "cc_sessions_2");
6496
- TASK_LABEL_3 = "synkro-local-cc-3";
6497
- TMUX_SESSION_3 = "synkro-local-cc-3";
6498
- SESSION_DIR_3 = join9(homedir9(), ".synkro", "cc_sessions_3");
6499
- TASK_LABEL_4 = "synkro-local-cc-4";
6500
- TMUX_SESSION_4 = "synkro-local-cc-4";
6501
- SESSION_DIR_4 = join9(homedir9(), ".synkro", "cc_sessions_4");
6502
- PueueError = class extends Error {
6503
- constructor(message, cause) {
6504
- super(message);
6505
- this.cause = cause;
6506
- this.name = "PueueError";
6507
- }
6508
- cause;
6509
- };
6510
- CHANNEL_PRIMARY = { taskLabel: TASK_LABEL, tmuxSession: TMUX_SESSION, sessionDir: SESSION_DIR };
6511
- CHANNEL_SECONDARY = { taskLabel: TASK_LABEL_2, tmuxSession: TMUX_SESSION_2, sessionDir: SESSION_DIR_2 };
6512
- CHANNEL_TERTIARY = { taskLabel: TASK_LABEL_3, tmuxSession: TMUX_SESSION_3, sessionDir: SESSION_DIR_3 };
6513
- CHANNEL_QUATERNARY = { taskLabel: TASK_LABEL_4, tmuxSession: TMUX_SESSION_4, sessionDir: SESSION_DIR_4 };
6514
- }
6515
- });
6516
-
6517
6429
  // cli/local-cc/channelSource.ts
6518
6430
  var init_channelSource = __esm({
6519
6431
  "cli/local-cc/channelSource.ts"() {
@@ -6523,9 +6435,9 @@ var init_channelSource = __esm({
6523
6435
 
6524
6436
  // cli/local-cc/install.ts
6525
6437
  import { existsSync as existsSync10, mkdirSync as mkdirSync9, writeFileSync as writeFileSync8, readFileSync as readFileSync8, chmodSync as chmodSync3, copyFileSync, renameSync as renameSync4, unlinkSync as unlinkSync4, openSync, fsyncSync, closeSync } from "fs";
6526
- import { join as join10 } from "path";
6527
- import { homedir as homedir10 } from "os";
6528
- import { spawnSync as spawnSync4 } from "child_process";
6438
+ import { join as join9 } from "path";
6439
+ import { homedir as homedir9 } from "os";
6440
+ import { spawnSync as spawnSync3 } from "child_process";
6529
6441
  function safelyMutateClaudeJson(mutator) {
6530
6442
  if (!existsSync10(CLAUDE_JSON_PATH)) {
6531
6443
  return;
@@ -6601,47 +6513,47 @@ function uninstallLocalCC() {
6601
6513
  return dirty;
6602
6514
  });
6603
6515
  }
6604
- var CLAUDE_JSON_BACKUP_PATH, SESSION_DIR2, PLUGIN_PATH, PLUGIN_PKG_PATH, PLUGIN_SETTINGS_DIR, PLUGIN_SETTINGS_PATH, PROJECT_MCP_PATH, CLAUDE_JSON_PATH, RUN_SCRIPT_PATH, TMUX_SESSION_NAME, CHANNEL_1_PORT, SESSION_DIR_22, PLUGIN_PATH_2, PLUGIN_PKG_PATH_2, PLUGIN_SETTINGS_DIR_2, PLUGIN_SETTINGS_PATH_2, PROJECT_MCP_PATH_2, RUN_SCRIPT_PATH_2, TMUX_SESSION_NAME_2, CHANNEL_2_PORT, SESSION_DIR_32, PLUGIN_PATH_3, PLUGIN_PKG_PATH_3, PLUGIN_SETTINGS_DIR_3, PLUGIN_SETTINGS_PATH_3, PROJECT_MCP_PATH_3, RUN_SCRIPT_PATH_3, TMUX_SESSION_NAME_3, CHANNEL_3_PORT, SESSION_DIR_42, PLUGIN_PATH_4, PLUGIN_PKG_PATH_4, PLUGIN_SETTINGS_DIR_4, PLUGIN_SETTINGS_PATH_4, PROJECT_MCP_PATH_4, RUN_SCRIPT_PATH_4, TMUX_SESSION_NAME_4, CHANNEL_4_PORT, RUN_SCRIPT_SOURCE, RUN_SCRIPT_SOURCE_2, RUN_SCRIPT_SOURCE_3, RUN_SCRIPT_SOURCE_4, MCP_SERVER_NAME, PLUGIN_PACKAGE_JSON, LocalCCInstallError, CHANNELS;
6516
+ var CLAUDE_JSON_BACKUP_PATH, SESSION_DIR, PLUGIN_PATH, PLUGIN_PKG_PATH, PLUGIN_SETTINGS_DIR, PLUGIN_SETTINGS_PATH, PROJECT_MCP_PATH, CLAUDE_JSON_PATH, RUN_SCRIPT_PATH, TMUX_SESSION_NAME, CHANNEL_1_PORT, SESSION_DIR_2, PLUGIN_PATH_2, PLUGIN_PKG_PATH_2, PLUGIN_SETTINGS_DIR_2, PLUGIN_SETTINGS_PATH_2, PROJECT_MCP_PATH_2, RUN_SCRIPT_PATH_2, TMUX_SESSION_NAME_2, CHANNEL_2_PORT, SESSION_DIR_3, PLUGIN_PATH_3, PLUGIN_PKG_PATH_3, PLUGIN_SETTINGS_DIR_3, PLUGIN_SETTINGS_PATH_3, PROJECT_MCP_PATH_3, RUN_SCRIPT_PATH_3, TMUX_SESSION_NAME_3, CHANNEL_3_PORT, SESSION_DIR_4, PLUGIN_PATH_4, PLUGIN_PKG_PATH_4, PLUGIN_SETTINGS_DIR_4, PLUGIN_SETTINGS_PATH_4, PROJECT_MCP_PATH_4, RUN_SCRIPT_PATH_4, TMUX_SESSION_NAME_4, CHANNEL_4_PORT, RUN_SCRIPT_SOURCE, RUN_SCRIPT_SOURCE_2, RUN_SCRIPT_SOURCE_3, RUN_SCRIPT_SOURCE_4, MCP_SERVER_NAME, PLUGIN_PACKAGE_JSON, LocalCCInstallError, CHANNELS;
6605
6517
  var init_install2 = __esm({
6606
6518
  "cli/local-cc/install.ts"() {
6607
6519
  "use strict";
6608
6520
  init_channelSource();
6609
- CLAUDE_JSON_BACKUP_PATH = join10(homedir10(), ".claude.json.synkro-bak");
6610
- SESSION_DIR2 = join10(homedir10(), ".synkro", "cc_sessions");
6611
- PLUGIN_PATH = join10(SESSION_DIR2, "synkro-channel.ts");
6612
- PLUGIN_PKG_PATH = join10(SESSION_DIR2, "package.json");
6613
- PLUGIN_SETTINGS_DIR = join10(SESSION_DIR2, ".claude");
6614
- PLUGIN_SETTINGS_PATH = join10(PLUGIN_SETTINGS_DIR, "settings.json");
6615
- PROJECT_MCP_PATH = join10(SESSION_DIR2, ".mcp.json");
6616
- CLAUDE_JSON_PATH = join10(homedir10(), ".claude.json");
6617
- RUN_SCRIPT_PATH = join10(SESSION_DIR2, "run-claude.sh");
6521
+ CLAUDE_JSON_BACKUP_PATH = join9(homedir9(), ".claude.json.synkro-bak");
6522
+ SESSION_DIR = join9(homedir9(), ".synkro", "cc_sessions");
6523
+ PLUGIN_PATH = join9(SESSION_DIR, "synkro-channel.ts");
6524
+ PLUGIN_PKG_PATH = join9(SESSION_DIR, "package.json");
6525
+ PLUGIN_SETTINGS_DIR = join9(SESSION_DIR, ".claude");
6526
+ PLUGIN_SETTINGS_PATH = join9(PLUGIN_SETTINGS_DIR, "settings.json");
6527
+ PROJECT_MCP_PATH = join9(SESSION_DIR, ".mcp.json");
6528
+ CLAUDE_JSON_PATH = join9(homedir9(), ".claude.json");
6529
+ RUN_SCRIPT_PATH = join9(SESSION_DIR, "run-claude.sh");
6618
6530
  TMUX_SESSION_NAME = "synkro-local-cc";
6619
6531
  CHANNEL_1_PORT = 8941;
6620
- SESSION_DIR_22 = join10(homedir10(), ".synkro", "cc_sessions_2");
6621
- PLUGIN_PATH_2 = join10(SESSION_DIR_22, "synkro-channel.ts");
6622
- PLUGIN_PKG_PATH_2 = join10(SESSION_DIR_22, "package.json");
6623
- PLUGIN_SETTINGS_DIR_2 = join10(SESSION_DIR_22, ".claude");
6624
- PLUGIN_SETTINGS_PATH_2 = join10(PLUGIN_SETTINGS_DIR_2, "settings.json");
6625
- PROJECT_MCP_PATH_2 = join10(SESSION_DIR_22, ".mcp.json");
6626
- RUN_SCRIPT_PATH_2 = join10(SESSION_DIR_22, "run-claude.sh");
6532
+ SESSION_DIR_2 = join9(homedir9(), ".synkro", "cc_sessions_2");
6533
+ PLUGIN_PATH_2 = join9(SESSION_DIR_2, "synkro-channel.ts");
6534
+ PLUGIN_PKG_PATH_2 = join9(SESSION_DIR_2, "package.json");
6535
+ PLUGIN_SETTINGS_DIR_2 = join9(SESSION_DIR_2, ".claude");
6536
+ PLUGIN_SETTINGS_PATH_2 = join9(PLUGIN_SETTINGS_DIR_2, "settings.json");
6537
+ PROJECT_MCP_PATH_2 = join9(SESSION_DIR_2, ".mcp.json");
6538
+ RUN_SCRIPT_PATH_2 = join9(SESSION_DIR_2, "run-claude.sh");
6627
6539
  TMUX_SESSION_NAME_2 = "synkro-local-cc-2";
6628
6540
  CHANNEL_2_PORT = 8951;
6629
- SESSION_DIR_32 = join10(homedir10(), ".synkro", "cc_sessions_3");
6630
- PLUGIN_PATH_3 = join10(SESSION_DIR_32, "synkro-channel.ts");
6631
- PLUGIN_PKG_PATH_3 = join10(SESSION_DIR_32, "package.json");
6632
- PLUGIN_SETTINGS_DIR_3 = join10(SESSION_DIR_32, ".claude");
6633
- PLUGIN_SETTINGS_PATH_3 = join10(PLUGIN_SETTINGS_DIR_3, "settings.json");
6634
- PROJECT_MCP_PATH_3 = join10(SESSION_DIR_32, ".mcp.json");
6635
- RUN_SCRIPT_PATH_3 = join10(SESSION_DIR_32, "run-claude.sh");
6541
+ SESSION_DIR_3 = join9(homedir9(), ".synkro", "cc_sessions_3");
6542
+ PLUGIN_PATH_3 = join9(SESSION_DIR_3, "synkro-channel.ts");
6543
+ PLUGIN_PKG_PATH_3 = join9(SESSION_DIR_3, "package.json");
6544
+ PLUGIN_SETTINGS_DIR_3 = join9(SESSION_DIR_3, ".claude");
6545
+ PLUGIN_SETTINGS_PATH_3 = join9(PLUGIN_SETTINGS_DIR_3, "settings.json");
6546
+ PROJECT_MCP_PATH_3 = join9(SESSION_DIR_3, ".mcp.json");
6547
+ RUN_SCRIPT_PATH_3 = join9(SESSION_DIR_3, "run-claude.sh");
6636
6548
  TMUX_SESSION_NAME_3 = "synkro-local-cc-3";
6637
6549
  CHANNEL_3_PORT = 8942;
6638
- SESSION_DIR_42 = join10(homedir10(), ".synkro", "cc_sessions_4");
6639
- PLUGIN_PATH_4 = join10(SESSION_DIR_42, "synkro-channel.ts");
6640
- PLUGIN_PKG_PATH_4 = join10(SESSION_DIR_42, "package.json");
6641
- PLUGIN_SETTINGS_DIR_4 = join10(SESSION_DIR_42, ".claude");
6642
- PLUGIN_SETTINGS_PATH_4 = join10(PLUGIN_SETTINGS_DIR_4, "settings.json");
6643
- PROJECT_MCP_PATH_4 = join10(SESSION_DIR_42, ".mcp.json");
6644
- RUN_SCRIPT_PATH_4 = join10(SESSION_DIR_42, "run-claude.sh");
6550
+ SESSION_DIR_4 = join9(homedir9(), ".synkro", "cc_sessions_4");
6551
+ PLUGIN_PATH_4 = join9(SESSION_DIR_4, "synkro-channel.ts");
6552
+ PLUGIN_PKG_PATH_4 = join9(SESSION_DIR_4, "package.json");
6553
+ PLUGIN_SETTINGS_DIR_4 = join9(SESSION_DIR_4, ".claude");
6554
+ PLUGIN_SETTINGS_PATH_4 = join9(PLUGIN_SETTINGS_DIR_4, "settings.json");
6555
+ PROJECT_MCP_PATH_4 = join9(SESSION_DIR_4, ".mcp.json");
6556
+ RUN_SCRIPT_PATH_4 = join9(SESSION_DIR_4, "run-claude.sh");
6645
6557
  TMUX_SESSION_NAME_4 = "synkro-local-cc-4";
6646
6558
  CHANNEL_4_PORT = 8952;
6647
6559
  RUN_SCRIPT_SOURCE = `#!/usr/bin/env bash
@@ -6902,10 +6814,10 @@ log "tmux session ended."
6902
6814
  cause;
6903
6815
  };
6904
6816
  CHANNELS = [
6905
- { sessionDir: SESSION_DIR2, pluginPath: PLUGIN_PATH, pluginPkgPath: PLUGIN_PKG_PATH, pluginSettingsDir: PLUGIN_SETTINGS_DIR, pluginSettingsPath: PLUGIN_SETTINGS_PATH, projectMcpPath: PROJECT_MCP_PATH, runScriptPath: RUN_SCRIPT_PATH, runScriptSource: RUN_SCRIPT_SOURCE },
6906
- { sessionDir: SESSION_DIR_22, pluginPath: PLUGIN_PATH_2, pluginPkgPath: PLUGIN_PKG_PATH_2, pluginSettingsDir: PLUGIN_SETTINGS_DIR_2, pluginSettingsPath: PLUGIN_SETTINGS_PATH_2, projectMcpPath: PROJECT_MCP_PATH_2, runScriptPath: RUN_SCRIPT_PATH_2, runScriptSource: RUN_SCRIPT_SOURCE_2 },
6907
- { sessionDir: SESSION_DIR_32, pluginPath: PLUGIN_PATH_3, pluginPkgPath: PLUGIN_PKG_PATH_3, pluginSettingsDir: PLUGIN_SETTINGS_DIR_3, pluginSettingsPath: PLUGIN_SETTINGS_PATH_3, projectMcpPath: PROJECT_MCP_PATH_3, runScriptPath: RUN_SCRIPT_PATH_3, runScriptSource: RUN_SCRIPT_SOURCE_3 },
6908
- { sessionDir: SESSION_DIR_42, pluginPath: PLUGIN_PATH_4, pluginPkgPath: PLUGIN_PKG_PATH_4, pluginSettingsDir: PLUGIN_SETTINGS_DIR_4, pluginSettingsPath: PLUGIN_SETTINGS_PATH_4, projectMcpPath: PROJECT_MCP_PATH_4, runScriptPath: RUN_SCRIPT_PATH_4, runScriptSource: RUN_SCRIPT_SOURCE_4 }
6817
+ { sessionDir: SESSION_DIR, pluginPath: PLUGIN_PATH, pluginPkgPath: PLUGIN_PKG_PATH, pluginSettingsDir: PLUGIN_SETTINGS_DIR, pluginSettingsPath: PLUGIN_SETTINGS_PATH, projectMcpPath: PROJECT_MCP_PATH, runScriptPath: RUN_SCRIPT_PATH, runScriptSource: RUN_SCRIPT_SOURCE },
6818
+ { sessionDir: SESSION_DIR_2, pluginPath: PLUGIN_PATH_2, pluginPkgPath: PLUGIN_PKG_PATH_2, pluginSettingsDir: PLUGIN_SETTINGS_DIR_2, pluginSettingsPath: PLUGIN_SETTINGS_PATH_2, projectMcpPath: PROJECT_MCP_PATH_2, runScriptPath: RUN_SCRIPT_PATH_2, runScriptSource: RUN_SCRIPT_SOURCE_2 },
6819
+ { sessionDir: SESSION_DIR_3, pluginPath: PLUGIN_PATH_3, pluginPkgPath: PLUGIN_PKG_PATH_3, pluginSettingsDir: PLUGIN_SETTINGS_DIR_3, pluginSettingsPath: PLUGIN_SETTINGS_PATH_3, projectMcpPath: PROJECT_MCP_PATH_3, runScriptPath: RUN_SCRIPT_PATH_3, runScriptSource: RUN_SCRIPT_SOURCE_3 },
6820
+ { sessionDir: SESSION_DIR_4, pluginPath: PLUGIN_PATH_4, pluginPkgPath: PLUGIN_PKG_PATH_4, pluginSettingsDir: PLUGIN_SETTINGS_DIR_4, pluginSettingsPath: PLUGIN_SETTINGS_PATH_4, projectMcpPath: PROJECT_MCP_PATH_4, runScriptPath: RUN_SCRIPT_PATH_4, runScriptSource: RUN_SCRIPT_SOURCE_4 }
6909
6821
  ];
6910
6822
  }
6911
6823
  });
@@ -6916,26 +6828,24 @@ __export(disconnect_exports, {
6916
6828
  disconnectCommand: () => disconnectCommand
6917
6829
  });
6918
6830
  import { existsSync as existsSync11, rmSync } from "fs";
6919
- import { homedir as homedir11 } from "os";
6920
- import { join as join11 } from "path";
6921
- function tearDownLocalCC() {
6831
+ import { homedir as homedir10 } from "os";
6832
+ import { join as join10 } from "path";
6833
+ import { spawnSync as spawnSync4 } from "child_process";
6834
+ function tearDownLocalCC(purge) {
6922
6835
  const docker = dockerStatus();
6923
6836
  if (docker.running) {
6924
6837
  dockerStop();
6925
- console.log("\u2713 local-cc runtime: stopped synkro-server container");
6926
- }
6927
- let hadTask = false;
6928
- try {
6929
- const tasks = [findTask(), findTask(CHANNEL_SECONDARY), findTask(CHANNEL_TERTIARY), findTask(CHANNEL_QUATERNARY)];
6930
- hadTask = tasks.some((t) => !!t);
6931
- stopTask();
6932
- stopTask(CHANNEL_SECONDARY);
6933
- stopTask(CHANNEL_TERTIARY);
6934
- stopTask(CHANNEL_QUATERNARY);
6935
- } catch {
6838
+ console.log("\u2713 stopped synkro-server container");
6839
+ } else {
6840
+ console.log("\xB7 no synkro-server container running");
6936
6841
  }
6937
- if (!docker.running) {
6938
- console.log(`${hadTask ? "\u2713" : "\xB7"} local-cc runtime: ${hadTask ? "stopped all pueue channels" : "no live tasks"}`);
6842
+ if (purge) {
6843
+ try {
6844
+ const image = imageTag();
6845
+ spawnSync4("docker", ["rmi", image], { encoding: "utf-8", timeout: 3e4 });
6846
+ console.log(`\u2713 removed Docker image ${image}`);
6847
+ } catch {
6848
+ }
6939
6849
  }
6940
6850
  if (needsKeychainBridge()) {
6941
6851
  try {
@@ -6945,12 +6855,12 @@ function tearDownLocalCC() {
6945
6855
  }
6946
6856
  }
6947
6857
  uninstallLocalCC();
6948
- console.log("\u2713 local-cc config: cleaned ~/.claude.json entries");
6858
+ console.log("\u2713 cleaned ~/.claude.json entries");
6949
6859
  }
6950
6860
  function disconnectCommand(args2 = []) {
6951
6861
  const purge = args2.includes("--purge");
6952
6862
  console.log("Synkro disconnect starting...\n");
6953
- tearDownLocalCC();
6863
+ tearDownLocalCC(purge);
6954
6864
  const agents = detectAgents();
6955
6865
  let sawClaudeCode = false;
6956
6866
  for (const agent of agents) {
@@ -6991,18 +6901,17 @@ var init_disconnect = __esm({
6991
6901
  init_ccHookConfig();
6992
6902
  init_cursorHookConfig();
6993
6903
  init_mcpConfig();
6994
- init_pueue();
6995
6904
  init_install2();
6996
6905
  init_dockerInstall();
6997
6906
  init_macKeychain();
6998
- SYNKRO_DIR5 = join11(homedir11(), ".synkro");
6907
+ SYNKRO_DIR5 = join10(homedir10(), ".synkro");
6999
6908
  }
7000
6909
  });
7001
6910
 
7002
6911
  // cli/local-cc/turnLog.ts
7003
6912
  import { appendFileSync, existsSync as existsSync12, mkdirSync as mkdirSync10, openSync as openSync2, readFileSync as readFileSync9, readSync, closeSync as closeSync2, statSync as statSync2, watchFile, unwatchFile } from "fs";
7004
- import { dirname as dirname5, join as join12 } from "path";
7005
- import { homedir as homedir12 } from "os";
6913
+ import { dirname as dirname5, join as join11 } from "path";
6914
+ import { homedir as homedir11 } from "os";
7006
6915
  function truncate(s, max = PREVIEW_MAX) {
7007
6916
  if (s.length <= max) return s;
7008
6917
  return s.slice(0, max) + "\u2026 [+" + (s.length - max) + " chars]";
@@ -7041,14 +6950,14 @@ var TURN_LOG_PATH, PREVIEW_MAX;
7041
6950
  var init_turnLog = __esm({
7042
6951
  "cli/local-cc/turnLog.ts"() {
7043
6952
  "use strict";
7044
- TURN_LOG_PATH = join12(homedir12(), ".synkro", "cc_sessions", "turns.log");
6953
+ TURN_LOG_PATH = join11(homedir11(), ".synkro", "cc_sessions", "turns.log");
7045
6954
  PREVIEW_MAX = 400;
7046
6955
  }
7047
6956
  });
7048
6957
 
7049
6958
  // cli/local-cc/client.ts
7050
6959
  import { request as httpRequest } from "http";
7051
- import { connect as connect2 } from "net";
6960
+ import { connect } from "net";
7052
6961
  async function submitToChannel(role, payload, opts = {}) {
7053
6962
  const body = JSON.stringify({ role, payload, content: payload });
7054
6963
  const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
@@ -7198,7 +7107,7 @@ var args = process.argv.slice(2);
7198
7107
  var cmd = args[0] || "";
7199
7108
  var subArgs = args.slice(1);
7200
7109
  function printVersion() {
7201
- console.log("1.4.89");
7110
+ console.log("1.4.90");
7202
7111
  }
7203
7112
  function printHelp() {
7204
7113
  console.log(`Synkro CLI \u2014 runtime safety for AI coding agents