@synkro-sh/cli 1.6.42 → 1.6.44

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
@@ -19,7 +19,7 @@ var __export = (target, all) => {
19
19
  import { existsSync } from "fs";
20
20
  import { homedir } from "os";
21
21
  import { join } from "path";
22
- import { execSync } from "child_process";
22
+ import { execFileSync, execSync } from "child_process";
23
23
  function which(cmd2) {
24
24
  try {
25
25
  const result = execSync(`which ${cmd2}`, { encoding: "utf-8" }).trim();
@@ -30,8 +30,9 @@ function which(cmd2) {
30
30
  }
31
31
  function getVersion(cmd2) {
32
32
  try {
33
- const result = execSync(`${cmd2} --version 2>&1`, { encoding: "utf-8", timeout: 5e3 }).trim();
34
- return result.split("\n")[0];
33
+ const result = execFileSync(cmd2, ["--version"], { encoding: "utf-8", timeout: 5e3 }).trim();
34
+ const line = result.split("\n")[0];
35
+ return line.replace(/\s*\(Claude Code\)/, "");
35
36
  } catch {
36
37
  return void 0;
37
38
  }
@@ -1498,7 +1499,12 @@ async function cloudGrade(surface: string, prompt: string, jwt: string, timeoutM
1498
1499
  return String(data.verdict || '');
1499
1500
  }
1500
1501
 
1501
- export async function localGrade(surface: string, prompt: string, timeoutMs = 30000, agentKind: AgentKind = 'claude_code'): Promise<string> {
1502
+ // Default 24s \u2014 MUST stay below the CC hook timeout (30s for edit/bash/cwe in
1503
+ // ccHookConfig.ts) so the AbortSignal fires and the caller's catch fails open
1504
+ // cleanly. If this matches or exceeds the CC budget, CC force-kills the bun
1505
+ // process mid-fetch (exit 142 / SIGALRM) and surfaces the in-flight grader
1506
+ // prompt as a hook error instead of a clean pass.
1507
+ export async function localGrade(surface: string, prompt: string, timeoutMs = 24000, agentKind: AgentKind = 'claude_code'): Promise<string> {
1502
1508
  const jwt = loadJwt();
1503
1509
  if (!jwt) throw new Error('NO_JWT');
1504
1510
  // BYOK grading mode routes the grade through an LLM API instead of the
@@ -1510,7 +1516,10 @@ export async function localGrade(surface: string, prompt: string, timeoutMs = 30
1510
1516
  return channelGrade(ROLE_MAP[surface] || 'grade-edit', prompt, jwt, 18929, timeoutMs, agentKind);
1511
1517
  }
1512
1518
 
1513
- export async function localGradeCwe(prompt: string, agentKind: AgentKind = 'claude_code', timeoutMs = 45000): Promise<string> {
1519
+ // Default 24s \u2014 was 45000, which EXCEEDED the CC cwe hook timeout (30s) and
1520
+ // guaranteed a force-kill on any slow grade. Two cwe chunks grade in parallel
1521
+ // within the same CC budget, so each must finish well under it.
1522
+ export async function localGradeCwe(prompt: string, agentKind: AgentKind = 'claude_code', timeoutMs = 24000): Promise<string> {
1514
1523
  const jwt = loadJwt();
1515
1524
  if (!jwt) throw new Error('NO_JWT');
1516
1525
  return channelGrade('grade-cwe', prompt, jwt, 18930, timeoutMs, agentKind);
@@ -6581,7 +6590,7 @@ var init_githubSetup = __esm({
6581
6590
  });
6582
6591
 
6583
6592
  // cli/commands/repoConnect.ts
6584
- import { execSync as execSync3, execFileSync } from "child_process";
6593
+ import { execSync as execSync3, execFileSync as execFileSync2 } from "child_process";
6585
6594
  import { readdirSync } from "fs";
6586
6595
  import { createServer as createServer2 } from "http";
6587
6596
  import { createInterface } from "readline";
@@ -6605,7 +6614,7 @@ function detectSubdirRepos() {
6605
6614
  for (const entry of entries) {
6606
6615
  if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
6607
6616
  try {
6608
- const remoteUrl = execFileSync("git", ["-C", entry.name, "remote", "get-url", "origin"], {
6617
+ const remoteUrl = execFileSync2("git", ["-C", entry.name, "remote", "get-url", "origin"], {
6609
6618
  encoding: "utf-8",
6610
6619
  timeout: 5e3,
6611
6620
  stdio: ["pipe", "pipe", "pipe"]
@@ -8261,7 +8270,7 @@ function writeConfigEnv(opts) {
8261
8270
  `SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
8262
8271
  `SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
8263
8272
  `SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
8264
- `SYNKRO_VERSION=${shellQuoteSingle("1.6.42")}`
8273
+ `SYNKRO_VERSION=${shellQuoteSingle("1.6.44")}`
8265
8274
  ];
8266
8275
  if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle(safeSynkroBin)}`);
8267
8276
  if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
@@ -8438,28 +8447,59 @@ async function installCommand(opts = {}) {
8438
8447
  const ghToken = null;
8439
8448
  setApiBaseUrl(`${gatewayUrl}/api`);
8440
8449
  await promptRepoConnection({ linkRepo: opts.linkRepo });
8450
+ const existingSynkro = readFullSynkroFile();
8441
8451
  const detected = detectAgents();
8442
- if (detected.length === 0) {
8443
- console.error("No supported coding agents detected. Install Claude Code or Cursor first.");
8444
- process.exit(1);
8445
- }
8446
- console.log("Detected agents:");
8447
- for (const a of detected) {
8448
- console.log(` \u2713 ${a.name}${a.version ? ` (${a.version})` : ""}`);
8449
- }
8450
- console.log();
8451
- const agents = await promptAgentSelection(detected);
8452
- if (agents.length < detected.length) {
8453
- console.log(`Installing hooks for: ${agents.map((a) => a.name).join(", ")}
8452
+ let agents;
8453
+ let gradingMode;
8454
+ let storageMode;
8455
+ let transcriptConsent = true;
8456
+ if (existingSynkro) {
8457
+ const wantCC = existingSynkro.harness.includes("claude-code");
8458
+ const wantCursor = existingSynkro.harness.includes("cursor");
8459
+ agents = detected.filter(
8460
+ (a) => a.kind === "claude_code" && wantCC || a.kind === "cursor" && wantCursor
8461
+ );
8462
+ if (agents.length === 0 && detected.length > 0) agents = detected;
8463
+ gradingMode = existingSynkro.grader.mode === "byok" ? "byok" : "local";
8464
+ storageMode = "local";
8465
+ console.log(`Using .synkro config:`);
8466
+ console.log(` harness: ${existingSynkro.harness.join(", ")}`);
8467
+ console.log(` grading: ${gradingMode} pool: ${existingSynkro.grader.pool}`);
8468
+ for (const a of agents) {
8469
+ console.log(` \u2713 ${a.name}${a.version ? ` (${a.version})` : ""}`);
8470
+ }
8471
+ console.log();
8472
+ } else {
8473
+ if (detected.length === 0) {
8474
+ console.error("No supported coding agents detected. Install Claude Code or Cursor first.");
8475
+ process.exit(1);
8476
+ }
8477
+ console.log("Detected agents:");
8478
+ for (const a of detected) {
8479
+ console.log(` \u2713 ${a.name}${a.version ? ` (${a.version})` : ""}`);
8480
+ }
8481
+ console.log();
8482
+ agents = await promptAgentSelection(detected);
8483
+ if (agents.length < detected.length) {
8484
+ console.log(`Installing hooks for: ${agents.map((a) => a.name).join(", ")}
8454
8485
  `);
8455
- }
8456
- const gradingMode = await promptGradingMode();
8457
- const storageMode = await promptStorageMode();
8458
- console.log(` grading: ${gradingMode} storage: ${storageMode}
8486
+ }
8487
+ gradingMode = await promptGradingMode();
8488
+ storageMode = await promptStorageMode();
8489
+ console.log(` grading: ${gradingMode} storage: ${storageMode}
8459
8490
  `);
8460
- if (gradingMode === "byok") {
8461
- console.log(" BYOK grading uses your own provider key \u2014 register one in the");
8462
- console.log(" dashboard under Settings \u2192 Provider Keys if you have not already.\n");
8491
+ if (gradingMode === "byok") {
8492
+ console.log(" BYOK grading uses your own provider key \u2014 register one in the");
8493
+ console.log(" dashboard under Settings \u2192 Provider Keys if you have not already.\n");
8494
+ }
8495
+ if (process.stdin.isTTY) {
8496
+ transcriptConsent = await promptTranscriptConsent();
8497
+ if (transcriptConsent) {
8498
+ console.log(" \u2713 Session import enabled\n");
8499
+ } else {
8500
+ console.log(" \u2717 Session import skipped\n");
8501
+ }
8502
+ }
8463
8503
  }
8464
8504
  ensureSynkroDir();
8465
8505
  const scripts = writeHookScripts();
@@ -8475,15 +8515,6 @@ async function installCommand(opts = {}) {
8475
8515
  } catch {
8476
8516
  }
8477
8517
  }
8478
- let transcriptConsent = true;
8479
- if (process.stdin.isTTY) {
8480
- transcriptConsent = await promptTranscriptConsent();
8481
- if (transcriptConsent) {
8482
- console.log(" \u2713 Session import enabled\n");
8483
- } else {
8484
- console.log(" \u2717 Session import skipped\n");
8485
- }
8486
- }
8487
8518
  let hasClaudeCode = false;
8488
8519
  let hasCursor = false;
8489
8520
  for (const agent of agents) {
@@ -10243,7 +10274,7 @@ var init_grade = __esm({
10243
10274
  });
10244
10275
 
10245
10276
  // cli/local-cc/pueue.ts
10246
- import { execFileSync as execFileSync2, spawnSync as spawnSync6, spawn } from "child_process";
10277
+ import { execFileSync as execFileSync3, spawnSync as spawnSync6, spawn } from "child_process";
10247
10278
  import { homedir as homedir12 } from "os";
10248
10279
  import { join as join12 } from "path";
10249
10280
  import { connect as connect2 } from "net";
@@ -11324,7 +11355,7 @@ var args = process.argv.slice(2);
11324
11355
  var cmd = args[0] || "";
11325
11356
  var subArgs = args.slice(1);
11326
11357
  function printVersion() {
11327
- console.log("1.6.42");
11358
+ console.log("1.6.44");
11328
11359
  }
11329
11360
  function printHelp2() {
11330
11361
  console.log(`Synkro CLI \u2014 runtime safety for AI coding agents