@synkro-sh/cli 1.4.35 → 1.4.37

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
@@ -198,20 +198,18 @@ function installCCHooks(settingsPath, config) {
198
198
  ],
199
199
  [SYNKRO_MARKER]: true
200
200
  });
201
- if (!config.skipTranscriptSync) {
202
- settings.hooks.Stop = settings.hooks.Stop ?? [];
203
- removeSynkroEntries(settings.hooks, "Stop");
204
- settings.hooks.Stop.push({
205
- hooks: [
206
- {
207
- type: "command",
208
- command: config.transcriptSyncScriptPath,
209
- timeout: 3
210
- }
211
- ],
212
- [SYNKRO_MARKER]: true
213
- });
214
- }
201
+ settings.hooks.Stop = settings.hooks.Stop ?? [];
202
+ removeSynkroEntries(settings.hooks, "Stop");
203
+ settings.hooks.Stop.push({
204
+ hooks: [
205
+ {
206
+ type: "command",
207
+ command: config.transcriptSyncScriptPath,
208
+ timeout: 3
209
+ }
210
+ ],
211
+ [SYNKRO_MARKER]: true
212
+ });
215
213
  writeSettingsAtomic(settingsPath, settings);
216
214
  }
217
215
  function uninstallCCHooks(settingsPath) {
@@ -1294,30 +1292,36 @@ CWD=$(echo "$PAYLOAD" | jq -r '.cwd // empty' 2>/dev/null)
1294
1292
  TRANSCRIPT_PATH=$(echo "$PAYLOAD" | jq -r '.transcript_path // empty' 2>/dev/null)
1295
1293
  GIT_REPO=$(synkro_detect_repo "\${CWD:-.}")
1296
1294
 
1297
- # Fire-and-forget usage telemetry
1295
+ # Aggregate token usage across all assistant turns in the transcript and POST silently
1298
1296
  if [ -n "$TRANSCRIPT_PATH" ] && [ -f "$TRANSCRIPT_PATH" ]; then
1299
1297
  (
1300
1298
  _LAST=$(grep '"type":"assistant"' "$TRANSCRIPT_PATH" 2>/dev/null | tail -1)
1301
- if [ -n "$_LAST" ]; then
1302
- CC_MODEL=$(echo "$_LAST" | jq -r '.message.model // empty' 2>/dev/null)
1303
- CC_USAGE=$(echo "$_LAST" | jq -c '{input_tokens:.message.usage.input_tokens,output_tokens:.message.usage.output_tokens,cache_creation_input_tokens:.message.usage.cache_creation_input_tokens,cache_read_input_tokens:.message.usage.cache_read_input_tokens}' 2>/dev/null || echo "{}")
1304
- HAS_TOKENS=$(echo "$CC_USAGE" | jq '(.input_tokens // 0) + (.output_tokens // 0)' 2>/dev/null)
1305
- if [ -n "$HAS_TOKENS" ] && [ "$HAS_TOKENS" != "0" ]; then
1306
- BODY=$(jq -n \\
1307
- --arg event_id "usage_$(date +%s)_$$" \\
1308
- --arg hook_type "stop" --arg verdict "allow" --arg severity "none" \\
1309
- --arg model "\${CC_MODEL:-claude-sonnet-4-6}" \\
1310
- --arg cc_model "\${CC_MODEL:-}" \\
1311
- --arg repo "\${GIT_REPO:-}" --arg session_id "$SESSION_ID" \\
1312
- --argjson cc_usage "$CC_USAGE" \\
1313
- '{capture_type:"local_verdict",event_id:$event_id,hook_type:$hook_type,verdict:$verdict,severity:$severity,model:$model,cc_usage:$cc_usage}
1314
- + (if $repo != "" then {repo:$repo} else {} end)
1315
- + (if $session_id != "" then {session_id:$session_id} else {} end)
1316
- + (if $cc_model != "" then {cc_model:$cc_model} else {} end)')
1317
- curl -sS -X POST "\${GATEWAY_URL}/api/v1/hook/capture" \\
1318
- -H "Content-Type: application/json" -H "Authorization: Bearer $JWT" \\
1319
- -d "$BODY" --max-time 2 >/dev/null 2>&1
1320
- fi
1299
+ CC_MODEL=$(echo "$_LAST" | jq -r '.message.model // empty' 2>/dev/null)
1300
+ TOTALS=$(grep '"type":"assistant"' "$TRANSCRIPT_PATH" 2>/dev/null \\
1301
+ | jq -c '.message.usage' 2>/dev/null \\
1302
+ | jq -s '{in:(map(.input_tokens//0)|add//0),out:(map(.output_tokens//0)|add//0),cw:(map(.cache_creation_input_tokens//0)|add//0),cr:(map(.cache_read_input_tokens//0)|add//0)}' 2>/dev/null \\
1303
+ || echo '{"in":0,"out":0,"cw":0,"cr":0}')
1304
+ TOK_IN=$(echo "$TOTALS" | jq -r '.in // 0')
1305
+ TOK_OUT=$(echo "$TOTALS" | jq -r '.out // 0')
1306
+ TOK_CW=$(echo "$TOTALS" | jq -r '.cw // 0')
1307
+ TOK_CR=$(echo "$TOTALS" | jq -r '.cr // 0')
1308
+ HAS_TOKENS=$(( TOK_IN + TOK_OUT ))
1309
+ if [ "$HAS_TOKENS" != "0" ]; then
1310
+ CC_USAGE="{"input_tokens":$TOK_IN,"output_tokens":$TOK_OUT,"cache_creation_input_tokens":$TOK_CW,"cache_read_input_tokens":$TOK_CR}"
1311
+ BODY=$(jq -n \\
1312
+ --arg event_id "usage_$(date +%s)_$$" \\
1313
+ --arg hook_type "stop" --arg verdict "allow" --arg severity "none" \\
1314
+ --arg model "\${CC_MODEL:-claude-sonnet-4-6}" \\
1315
+ --arg cc_model "\${CC_MODEL:-}" \\
1316
+ --arg repo "\${GIT_REPO:-}" --arg session_id "$SESSION_ID" \\
1317
+ --argjson cc_usage "$CC_USAGE" \\
1318
+ '{capture_type:"local_verdict",event_id:$event_id,hook_type:$hook_type,verdict:$verdict,severity:$severity,model:$model,cc_usage:$cc_usage}
1319
+ + (if $repo != "" then {repo:$repo} else {} end)
1320
+ + (if $session_id != "" then {session_id:$session_id} else {} end)
1321
+ + (if $cc_model != "" then {cc_model:$cc_model} else {} end)')
1322
+ curl -sS -X POST "\${GATEWAY_URL}/api/v1/hook/capture" \\
1323
+ -H "Content-Type: application/json" -H "Authorization: Bearer $JWT" \\
1324
+ -d "$BODY" --max-time 2 >/dev/null 2>&1
1321
1325
  fi
1322
1326
  ) &
1323
1327
  fi
@@ -1333,9 +1337,9 @@ FINDINGS=$(echo "$RESP" | jq -r '.findings // 0' 2>/dev/null)
1333
1337
  AUTO_FIXED=$(echo "$RESP" | jq -r '.auto_fixed // 0' 2>/dev/null)
1334
1338
  OPEN=$(echo "$RESP" | jq -r '.open // 0' 2>/dev/null)
1335
1339
 
1336
- if [ "$EDITS" = "0" ] || [ -z "$EDITS" ]; then echo '{}'; exit 0; fi
1340
+ if [ "\${EDITS:-0}" = "0" ] || [ -z "$EDITS" ]; then echo '{}'; exit 0; fi
1337
1341
 
1338
- if [ "$FINDINGS" = "0" ] || [ -z "$FINDINGS" ]; then
1342
+ if [ "\${FINDINGS:-0}" = "0" ] || [ -z "$FINDINGS" ]; then
1339
1343
  SYS_MSG="[synkro] stop \u2192 0 issues across \${EDITS} edit(s), session complete"
1340
1344
  else
1341
1345
  SYS_MSG="[synkro] stop \u2192 \${FINDINGS} finding(s): \${AUTO_FIXED} auto-fixed, \${OPEN} open"
@@ -1444,7 +1448,6 @@ SCRIPT_DIR="$(cd "$(dirname "\${BASH_SOURCE[0]}")" && pwd)"
1444
1448
 
1445
1449
  JWT=$(synkro_load_jwt)
1446
1450
  if [ -z "$JWT" ]; then echo '{}'; exit 0; fi
1447
- if [ "\${SYNKRO_TRANSCRIPT_CONSENT:-yes}" = "no" ]; then echo '{}'; exit 0; fi
1448
1451
 
1449
1452
  PAYLOAD=$(cat)
1450
1453
  SESSION_ID=$(echo "$PAYLOAD" | jq -r '.session_id // empty' 2>/dev/null)
@@ -1455,6 +1458,36 @@ if [ -z "$SESSION_ID" ] || [ -z "$TRANSCRIPT_PATH" ] || [ ! -f "$TRANSCRIPT_PATH
1455
1458
  echo '{}'; exit 0
1456
1459
  fi
1457
1460
 
1461
+ # Usage telemetry \u2014 last turn only (metadata, ungated by privacy/consent)
1462
+ _LAST_ASST=$(tail -20 "$TRANSCRIPT_PATH" 2>/dev/null | grep '"type":"assistant"' | tail -1)
1463
+ if [ -n "$_LAST_ASST" ]; then
1464
+ _CC_MODEL=$(echo "$_LAST_ASST" | jq -r '.message.model // empty' 2>/dev/null)
1465
+ _TI=$(echo "$_LAST_ASST" | jq -r '.message.usage.input_tokens // 0' 2>/dev/null)
1466
+ _TO=$(echo "$_LAST_ASST" | jq -r '.message.usage.output_tokens // 0' 2>/dev/null)
1467
+ _TCW=$(echo "$_LAST_ASST" | jq -r '.message.usage.cache_creation_input_tokens // 0' 2>/dev/null)
1468
+ _TCR=$(echo "$_LAST_ASST" | jq -r '.message.usage.cache_read_input_tokens // 0' 2>/dev/null)
1469
+ if [ "\${_TI:-0}" != "0" ] || [ "\${_TO:-0}" != "0" ]; then
1470
+ (
1471
+ _USAGE="{\\"input_tokens\\":$_TI,\\"output_tokens\\":$_TO,\\"cache_creation_input_tokens\\":$_TCW,\\"cache_read_input_tokens\\":$_TCR}"
1472
+ _BODY=$(jq -n \\
1473
+ --arg event_id "usage_$(date +%s)_$$" \\
1474
+ --arg hook_type "stop" --arg verdict "allow" --arg severity "none" \\
1475
+ --arg model "\${_CC_MODEL:-claude-sonnet-4-6}" \\
1476
+ --arg cc_model "\${_CC_MODEL:-}" \\
1477
+ --arg session_id "$SESSION_ID" \\
1478
+ --argjson cc_usage "$_USAGE" \\
1479
+ '{capture_type:"usage_tick",event_id:$event_id,hook_type:$hook_type,verdict:$verdict,severity:$severity,model:$model,cc_usage:$cc_usage,session_id:$session_id}
1480
+ + (if $cc_model != "" then {cc_model:$cc_model} else {} end)')
1481
+ curl -sS -X POST "\${GATEWAY_URL}/api/v1/hook/capture" \\
1482
+ -H "Content-Type: application/json" -H "Authorization: Bearer $JWT" \\
1483
+ -d "$_BODY" --max-time 2 >/dev/null 2>&1
1484
+ ) &
1485
+ fi
1486
+ fi
1487
+
1488
+ # Transcript sync below is gated by consent + capture depth
1489
+ if [ "\${SYNKRO_TRANSCRIPT_CONSENT:-yes}" = "no" ]; then echo '{}'; exit 0; fi
1490
+
1458
1491
  GIT_REPO=$(synkro_detect_repo "\${CWD:-.}")
1459
1492
  if [ -z "$GIT_REPO" ]; then echo '{}'; exit 0; fi
1460
1493
 
@@ -3907,7 +3940,7 @@ function writeConfigEnv(opts) {
3907
3940
  `SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
3908
3941
  `SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
3909
3942
  `SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
3910
- `SYNKRO_VERSION=${shellQuoteSingle("1.4.35")}`
3943
+ `SYNKRO_VERSION=${shellQuoteSingle("1.4.37")}`
3911
3944
  ];
3912
3945
  if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle(safeSynkroBin)}`);
3913
3946
  if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);