@synkro-sh/cli 1.7.24 → 1.7.30

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
@@ -269,14 +269,10 @@ function installCCHooks(settingsPath, config) {
269
269
  ],
270
270
  [SYNKRO_MARKER]: true
271
271
  });
272
- settings.env = settings.env ?? {};
273
- const existingBaseUrl = settings.env.ANTHROPIC_BASE_URL;
274
- if (!existingBaseUrl || existingBaseUrl === USAGE_PROXY_URL) {
275
- settings.env.ANTHROPIC_BASE_URL = USAGE_PROXY_URL;
276
- } else {
277
- console.warn(` \u26A0 ANTHROPIC_BASE_URL already set to ${existingBaseUrl} \u2014 leaving it; live usage capture is off for this agent.`);
272
+ if (settings.env && settings.env.ANTHROPIC_BASE_URL === USAGE_PROXY_URL) {
273
+ delete settings.env.ANTHROPIC_BASE_URL;
274
+ if (Object.keys(settings.env).length === 0) delete settings.env;
278
275
  }
279
- if (Object.keys(settings.env).length === 0) delete settings.env;
280
276
  writeSettingsAtomic(settingsPath, settings);
281
277
  }
282
278
  function uninstallCCHooks(settingsPath) {
@@ -7146,6 +7142,15 @@ async function main() {
7146
7142
  const usage = aggregateUsage(transcriptPath, { modelFallback });
7147
7143
  emitUsageTick({ sessionId, usage, hookType: 'prompt_submit', gitRepo, modelFallback });
7148
7144
  }
7145
+ // Nudge the local container to refresh account-wide coding-agent usage OUT OF BAND.
7146
+ // The endpoint returns 202 immediately and does its own Anthropic ping, so this
7147
+ // never gates the prompt; a stopped container just fails the fetch fast (caught).
7148
+ try {
7149
+ const usagePort = process.env.SYNKRO_MCP_HOST_PORT || '18931';
7150
+ await fetch('http://127.0.0.1:' + usagePort + '/api/local/usage-poll', {
7151
+ method: 'POST', signal: AbortSignal.timeout(1200),
7152
+ }).catch(() => {});
7153
+ } catch {}
7149
7154
  outputEmpty();
7150
7155
  } catch {
7151
7156
  outputEmpty();
@@ -7821,8 +7826,22 @@ export async function runStub(surface: string, opts: StubOpts = {}): Promise<voi
7821
7826
  // wait above that budget — not the 6s telemetry default — or the stub abandons
7822
7827
  // the request before the result lands and the completion shows up a hook late.
7823
7828
  const timeoutMs = surface === 'bash-followup' ? 32000 : (opts.telemetry ? 6000 : 28000);
7824
- const url = 'http://127.0.0.1:' + PORT + '/api/scan/' + surface + (harness === 'cursor' ? '?harness=cursor' : '');
7825
- const body = JSON.stringify(envelope);
7829
+ // Cloud has no local container to reach. Post the SAME envelope to the org's grader
7830
+ // via the gateway's /grade/submit as role 'scan:<surface>'; the container runs
7831
+ // scanRouter (runScan) server-side and returns the SAME shaped decision — so cloud
7832
+ // and local share ONE grading implementation, no client-side parsing. The gateway
7833
+ // accepts the durable 1yr MCP token (verifyOrg → org-derived, tenant-safe).
7834
+ const cloud = deployIsCloud();
7835
+ // Regex-free trailing-slash trim — this is inside a template literal, where a
7836
+ // regex like /\\/+$/ mis-escapes into broken emitted code (smoke:hooks catches it).
7837
+ let gwBase = cfgVal('SYNKRO_GATEWAY_URL') || 'https://api.synkro.sh';
7838
+ while (gwBase.endsWith('/')) gwBase = gwBase.slice(0, -1);
7839
+ const url = cloud
7840
+ ? gwBase + '/grade/submit'
7841
+ : 'http://127.0.0.1:' + PORT + '/api/scan/' + surface + (harness === 'cursor' ? '?harness=cursor' : '');
7842
+ const body = cloud
7843
+ ? JSON.stringify({ role: 'scan:' + surface, payload: JSON.stringify(envelope), content: '' })
7844
+ : JSON.stringify(envelope);
7826
7845
  const headers = { 'Content-Type': 'application/json', Authorization: 'Bearer ' + loadMcpJwt() };
7827
7846
  // Telemetry hooks (bash-followup, transcript-sync, session telemetry) IGNORE the
7828
7847
  // response and the server processes them DETACHED, so delivery RELIABILITY beats
@@ -10563,13 +10582,14 @@ async function dockerInstall(opts = {}) {
10563
10582
  }
10564
10583
  mkdirSync8(CURSOR_CREDS_DIR, { recursive: true });
10565
10584
  if (needsKeychainBridge()) {
10566
- if (claudeWorkers > 0) {
10567
- const path = exportKeychainCreds();
10568
- if (!path) {
10585
+ const claudeCredsPath = exportKeychainCreds();
10586
+ if (!claudeCredsPath) {
10587
+ if (claudeWorkers > 0) {
10569
10588
  throw new DockerInstallError(
10570
10589
  "Claude Code keychain entry not found. Run `claude login` (or open Claude Code and sign in) before installing the container."
10571
10590
  );
10572
10591
  }
10592
+ console.warn(" \u26A0 Claude Code keychain entry not found \u2014 live usage telemetry stays off until you sign in to Claude Code (grading is unaffected).");
10573
10593
  }
10574
10594
  if (cursorWorkers > 0 && !cursorApiKeyConfigured()) {
10575
10595
  console.warn(" \u26A0 No Cursor API key found \u2014 Cursor grader workers will be idle.");
@@ -10623,8 +10643,6 @@ async function dockerInstall(opts = {}) {
10623
10643
  "-p",
10624
10644
  `127.0.0.1:${HOST_CWE_PORT}:8930`,
10625
10645
  "-p",
10626
- `127.0.0.1:${HOST_USAGE_PROXY_PORT}:8927`,
10627
- "-p",
10628
10646
  `127.0.0.1:${HOST_PGLITE_PORT}:5433`,
10629
10647
  "-v",
10630
10648
  `${PGDATA_PATH}:/data/pgdata`,
@@ -10875,7 +10893,7 @@ function checkPgdata() {
10875
10893
  if (!hasPgControl) return { healthy: false, details: "pg_control/global directory missing" };
10876
10894
  return { healthy: true, details: `${entries.length} entries, WAL present, no stale PID` };
10877
10895
  }
10878
- var SYNKRO_DIR2, MCP_JWT_PATH, PGDATA_PATH, CLAUDE_HOST_STATE_DIR, CLAUDE_HOST_STATE_FILE, HOST_MCP_PORT, HOST_GRADER_PORT, HOST_CWE_PORT, HOST_USAGE_PROXY_PORT, HOST_PGLITE_PORT, CONTAINER_NAME, DEFAULT_IMAGE, DockerInstallError, BACKUP_DIR;
10896
+ var SYNKRO_DIR2, MCP_JWT_PATH, PGDATA_PATH, CLAUDE_HOST_STATE_DIR, CLAUDE_HOST_STATE_FILE, HOST_MCP_PORT, HOST_GRADER_PORT, HOST_CWE_PORT, HOST_PGLITE_PORT, CONTAINER_NAME, DEFAULT_IMAGE, DockerInstallError, BACKUP_DIR;
10879
10897
  var init_dockerInstall = __esm({
10880
10898
  "cli/local-cc/dockerInstall.ts"() {
10881
10899
  "use strict";
@@ -10889,7 +10907,6 @@ var init_dockerInstall = __esm({
10889
10907
  HOST_MCP_PORT = parseInt(process.env.SYNKRO_HOST_MCP_PORT || "18931", 10);
10890
10908
  HOST_GRADER_PORT = parseInt(process.env.SYNKRO_HOST_GRADER_PORT || "18929", 10);
10891
10909
  HOST_CWE_PORT = parseInt(process.env.SYNKRO_HOST_CWE_PORT || "18930", 10);
10892
- HOST_USAGE_PROXY_PORT = parseInt(process.env.SYNKRO_HOST_USAGE_PROXY_PORT || "18927", 10);
10893
10910
  HOST_PGLITE_PORT = parseInt(process.env.SYNKRO_HOST_PGLITE_PORT || "15433", 10);
10894
10911
  CONTAINER_NAME = "synkro-server";
10895
10912
  DEFAULT_IMAGE = "ghcr.io/synkro-sh/synkro-server:latest";
@@ -11756,7 +11773,7 @@ function writeConfigEnv(opts) {
11756
11773
  `SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
11757
11774
  `SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
11758
11775
  `SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
11759
- `SYNKRO_VERSION=${shellQuoteSingle("1.7.24")}`
11776
+ `SYNKRO_VERSION=${shellQuoteSingle("1.7.30")}`
11760
11777
  ];
11761
11778
  if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle(safeSynkroBin)}`);
11762
11779
  if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
@@ -12378,13 +12395,7 @@ async function installCommand(opts = {}) {
12378
12395
  }
12379
12396
  const transcriptConsent = transcriptCC || transcriptCursor;
12380
12397
  ensureSynkroDir();
12381
- let hookMode = opts.hookMode || resolvePersistedHookMode();
12382
- if (target === "cloud-container" && hookMode === "stub") {
12383
- if (opts.hookMode === "stub") {
12384
- console.log(" \u24D8 Cloud mode needs full hooks (stub hooks require a local container) \u2014 using full.\n");
12385
- }
12386
- hookMode = "full";
12387
- }
12398
+ const hookMode = opts.hookMode || resolvePersistedHookMode();
12388
12399
  const scripts = writeHookScripts(hookMode);
12389
12400
  console.log("Wrote hook scripts to ~/.synkro/hooks/\n");
12390
12401
  for (const mode of ["edit", "bash"]) {
@@ -15962,7 +15973,7 @@ var args = process.argv.slice(2);
15962
15973
  var cmd = args[0] || "";
15963
15974
  var subArgs = args.slice(1);
15964
15975
  function printVersion() {
15965
- console.log("1.7.24");
15976
+ console.log("1.7.30");
15966
15977
  }
15967
15978
  function printHelp2() {
15968
15979
  console.log(`Synkro CLI \u2014 runtime safety for AI coding agents