@synkro-sh/cli 1.3.43 → 1.3.45

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
@@ -617,18 +617,16 @@ if [ "$USE_LOCAL" = "true" ]; then
617
617
  # The daemon fetches the primer (Synkro IP) directly from the server at
618
618
  # startup and holds it in memory \u2014 never written to disk.
619
619
 
620
- # Fetch org guardrail rules. In local_only mode use GET (no command leaks);
621
- # in other modes use POST with content for embedding-based top_k matching.
622
620
  RULES_CACHE="$HOME/.synkro/.rules-cache-bash"
623
621
  ORG_RULES="[]"
624
622
  if [ "$SYNKRO_CAPTURE_DEPTH" = "local_only" ]; then
625
- if find "$RULES_CACHE" -mmin -60 2>/dev/null | grep -q .; then
623
+ ORG_RULES=$(curl -sS "\${GATEWAY_URL}/api/v1/cli/pr-rules" \\
624
+ -H "Authorization: Bearer $JWT" --max-time 3 2>/dev/null \\
625
+ | jq -c '[.rules[]? | {rule_id, text, severity, category}]' 2>/dev/null || echo "[]")
626
+ if [ -n "$ORG_RULES" ] && [ "$ORG_RULES" != "null" ] && [ "$ORG_RULES" != "[]" ]; then
627
+ printf '%s' "$ORG_RULES" > "$RULES_CACHE" 2>/dev/null || true
628
+ elif [ -f "$RULES_CACHE" ]; then
626
629
  ORG_RULES=$(cat "$RULES_CACHE" 2>/dev/null || echo "[]")
627
- else
628
- ORG_RULES=$(curl -sS "\${GATEWAY_URL}/api/v1/cli/pr-rules" \\
629
- -H "Authorization: Bearer $JWT" --max-time 2 2>/dev/null \\
630
- | jq -c '[.rules[]? | {rule_id, text, severity, category}]' 2>/dev/null || echo "[]")
631
- [ -n "$ORG_RULES" ] && [ "$ORG_RULES" != "null" ] && printf '%s' "$ORG_RULES" > "$RULES_CACHE" 2>/dev/null || true
632
630
  fi
633
631
  else
634
632
  ORG_RULES=$(printf '%s' "$COMMAND" | head -c 4000 \\
@@ -809,8 +807,8 @@ if [ "$SYNKRO_CAPTURE_DEPTH" = "local_only" ] && [ -n "$VERDICT_KIND" ]; then
809
807
  if [ -n "$CLASS_PROMPT" ]; then
810
808
  CLASS_INPUT=$(printf '%s\\n\\nViolation context:\\n- Tool: %s\\n- Category: %s\\n- Severity: %s\\n- Hook type: bash command judge' "$CLASS_PROMPT" "$TOOL_NAME" "$CATEGORY" "$SEVERITY")
811
809
  CLASS_RESP=$(echo "$CLASS_INPUT" | claude --print --model claude-sonnet-4-6 --no-session-persistence 2>/dev/null || echo "")
812
- MECH_CAT=$(echo "$CLASS_RESP" | jq -r '.mechanism_category // empty' 2>/dev/null)
813
- BIZ_CAT=$(echo "$CLASS_RESP" | jq -r '.business_category // empty' 2>/dev/null)
810
+ MECH_CAT=$(echo "$CLASS_RESP" | grep -oE '<mechanism>[^<]+</mechanism>' | sed 's/<[^>]*>//g')
811
+ BIZ_CAT=$(echo "$CLASS_RESP" | grep -oE '<business>[^<]+</business>' | sed 's/<[^>]*>//g')
814
812
  fi
815
813
  fi
816
814
  ANON_BODY=$(jq -n \\
@@ -1118,13 +1116,13 @@ if [ "$USE_LOCAL" = "true" ]; then
1118
1116
  RULES_CACHE="$HOME/.synkro/.rules-cache-edit"
1119
1117
  ORG_RULES="[]"
1120
1118
  if [ "$SYNKRO_CAPTURE_DEPTH" = "local_only" ]; then
1121
- if find "$RULES_CACHE" -mmin -60 2>/dev/null | grep -q .; then
1119
+ ORG_RULES=$(curl -sS "\${GATEWAY_URL}/api/v1/cli/pr-rules" \\
1120
+ -H "Authorization: Bearer $JWT" --max-time 3 2>/dev/null \\
1121
+ | jq -c '[.rules[]? | {rule_id, text, severity, category, mode}]' 2>/dev/null || echo "[]")
1122
+ if [ -n "$ORG_RULES" ] && [ "$ORG_RULES" != "null" ] && [ "$ORG_RULES" != "[]" ]; then
1123
+ printf '%s' "$ORG_RULES" > "$RULES_CACHE" 2>/dev/null || true
1124
+ elif [ -f "$RULES_CACHE" ]; then
1122
1125
  ORG_RULES=$(cat "$RULES_CACHE" 2>/dev/null || echo "[]")
1123
- else
1124
- ORG_RULES=$(curl -sS "\${GATEWAY_URL}/api/v1/cli/pr-rules" \\
1125
- -H "Authorization: Bearer $JWT" --max-time 2 2>/dev/null \\
1126
- | jq -c '[.rules[]? | {rule_id, text, severity, category, mode}]' 2>/dev/null || echo "[]")
1127
- [ -n "$ORG_RULES" ] && [ "$ORG_RULES" != "null" ] && printf '%s' "$ORG_RULES" > "$RULES_CACHE" 2>/dev/null || true
1128
1126
  fi
1129
1127
  else
1130
1128
  ORG_RULES=$(printf '%s' "$PROPOSED" | head -c 8000 \\
@@ -1320,8 +1318,8 @@ if [ "$SYNKRO_CAPTURE_DEPTH" = "local_only" ] && [ -n "$DECISION" ]; then
1320
1318
  if [ -n "$CLASS_PROMPT" ]; then
1321
1319
  CLASS_INPUT=$(printf '%s\\n\\nViolation context:\\n- Tool: %s\\n- Category: %s\\n- Severity: %s\\n- Hook type: edit pre-check judge' "$CLASS_PROMPT" "$TOOL_NAME" "$LOCAL_CATEGORY" "$LOCAL_SEVERITY")
1322
1320
  CLASS_RESP=$(echo "$CLASS_INPUT" | claude --print --model claude-sonnet-4-6 --no-session-persistence 2>/dev/null || echo "")
1323
- MECH_CAT=$(echo "$CLASS_RESP" | jq -r '.mechanism_category // empty' 2>/dev/null)
1324
- BIZ_CAT=$(echo "$CLASS_RESP" | jq -r '.business_category // empty' 2>/dev/null)
1321
+ MECH_CAT=$(echo "$CLASS_RESP" | grep -oE '<mechanism>[^<]+</mechanism>' | sed 's/<[^>]*>//g')
1322
+ BIZ_CAT=$(echo "$CLASS_RESP" | grep -oE '<business>[^<]+</business>' | sed 's/<[^>]*>//g')
1325
1323
  fi
1326
1324
  fi
1327
1325
  ANON_BODY=$(jq -n \\
@@ -1547,16 +1545,15 @@ fi
1547
1545
  if [ "$USE_LOCAL" = "true" ]; then
1548
1546
  # \u2500\u2500\u2500 LOCAL GRADING: grade via the persistent claude daemon (mode=edit). \u2500\u2500\u2500
1549
1547
 
1550
- # In local_only: GET all rules (no content sent), cache 1h. Otherwise POST with content.
1551
1548
  RULES_CACHE="$HOME/.synkro/.rules-cache-edit-capture"
1552
1549
  if [ "$SYNKRO_CAPTURE_DEPTH" = "local_only" ]; then
1553
- if find "$RULES_CACHE" -mmin -60 2>/dev/null | grep -q .; then
1550
+ ORG_RULES=$(curl -sS "\${GATEWAY_URL}/api/v1/cli/pr-rules" \\
1551
+ -H "Authorization: Bearer $JWT" --max-time 3 2>/dev/null \\
1552
+ | jq -c '[.rules[]? | {rule_id, text, severity, category}]' 2>/dev/null || echo "[]")
1553
+ if [ -n "$ORG_RULES" ] && [ "$ORG_RULES" != "null" ] && [ "$ORG_RULES" != "[]" ]; then
1554
+ printf '%s' "$ORG_RULES" > "$RULES_CACHE" 2>/dev/null || true
1555
+ elif [ -f "$RULES_CACHE" ]; then
1554
1556
  ORG_RULES=$(cat "$RULES_CACHE" 2>/dev/null || echo "[]")
1555
- else
1556
- ORG_RULES=$(curl -sS "\${GATEWAY_URL}/api/v1/cli/pr-rules" \\
1557
- -H "Authorization: Bearer $JWT" --max-time 2 2>/dev/null \\
1558
- | jq -c '[.rules[]? | {rule_id, text, severity, category}]' 2>/dev/null || echo "[]")
1559
- [ -n "$ORG_RULES" ] && [ "$ORG_RULES" != "null" ] && printf '%s' "$ORG_RULES" > "$RULES_CACHE" 2>/dev/null || true
1560
1557
  fi
1561
1558
  else
1562
1559
  ORG_RULES=$(printf '%s' "$FILE_CONTENT" | head -c 8000 \\
@@ -1663,8 +1660,8 @@ if [ "$SYNKRO_CAPTURE_DEPTH" = "local_only" ]; then
1663
1660
  if [ -n "$CLASS_PROMPT" ]; then
1664
1661
  CLASS_INPUT=$(printf '%s\\n\\nViolation context:\\n- Tool: %s\\n- Category: %s\\n- Severity: %s\\n- Hook type: post-edit capture grader' "$CLASS_PROMPT" "$TOOL_NAME" "$CATEGORY" "$LOCAL_SEVERITY")
1665
1662
  CLASS_RESP=$(echo "$CLASS_INPUT" | claude --print --model claude-sonnet-4-6 --no-session-persistence 2>/dev/null || echo "")
1666
- MECH_CAT=$(echo "$CLASS_RESP" | jq -r '.mechanism_category // empty' 2>/dev/null)
1667
- BIZ_CAT=$(echo "$CLASS_RESP" | jq -r '.business_category // empty' 2>/dev/null)
1663
+ MECH_CAT=$(echo "$CLASS_RESP" | grep -oE '<mechanism>[^<]+</mechanism>' | sed 's/<[^>]*>//g')
1664
+ BIZ_CAT=$(echo "$CLASS_RESP" | grep -oE '<business>[^<]+</business>' | sed 's/<[^>]*>//g')
1668
1665
  fi
1669
1666
  fi
1670
1667
  ANON_BODY=$(jq -n \\
@@ -2193,7 +2190,7 @@ def log(msg):
2193
2190
  pass
2194
2191
 
2195
2192
 
2196
- STALL_TIMEOUT_SEC = int(os.environ.get("SYNKRO_DAEMON_STALL_TIMEOUT", "10"))
2193
+ STALL_TIMEOUT_SEC = int(os.environ.get("SYNKRO_DAEMON_STALL_TIMEOUT", "15"))
2197
2194
 
2198
2195
  def _read_response(proc, timeout=45, stop_event=None):
2199
2196
  """Read stream-json from proc.stdout until a 'result' message arrives.
@@ -2353,7 +2350,7 @@ class WarmGrader:
2353
2350
  self._kill_proc(proc)
2354
2351
  proc = None
2355
2352
 
2356
- wall_limit = int(os.environ.get("SYNKRO_DAEMON_WALL_TIMEOUT", "12"))
2353
+ wall_limit = int(os.environ.get("SYNKRO_DAEMON_WALL_TIMEOUT", "20"))
2357
2354
  race_timeout = min(GRADE_TIMEOUT_SEC, wall_limit)
2358
2355
 
2359
2356
  # Race a warm and a fresh cold process. Whichever returns a non-empty
@@ -2367,7 +2364,7 @@ class WarmGrader:
2367
2364
 
2368
2365
  def grade_worker(p, label):
2369
2366
  try:
2370
- _send_msg(p, prompt)
2367
+ _send_msg(p, prompt, close_stdin=True)
2371
2368
  r = _read_response(p, timeout=race_timeout, stop_event=stop_event)
2372
2369
  if r:
2373
2370
  result_q.put((label, r))
@@ -3859,7 +3856,7 @@ function writeConfigEnv(opts) {
3859
3856
  `SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
3860
3857
  `SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
3861
3858
  `SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
3862
- `SYNKRO_VERSION=${shellQuoteSingle("1.3.43")}`
3859
+ `SYNKRO_VERSION=${shellQuoteSingle("1.3.45")}`
3863
3860
  ];
3864
3861
  if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
3865
3862
  if (safeOrgId) lines.push(`SYNKRO_ORG_ID=${shellQuoteSingle(safeOrgId)}`);