@synkro-sh/cli 1.3.31 → 1.3.32
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 +104 -56
- package/dist/bootstrap.js.map +1 -1
- package/package.json +1 -1
package/dist/bootstrap.js
CHANGED
|
@@ -1118,51 +1118,68 @@ if [ "$USE_LOCAL" = "true" ]; then
|
|
|
1118
1118
|
VERDICT_JSON='{"ok":true,"violations":[]}'
|
|
1119
1119
|
fi
|
|
1120
1120
|
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1121
|
+
if [ "$SYNKRO_CAPTURE_DEPTH" = "local_only" ]; then
|
|
1122
|
+
# No file content / diff / intent / actions leave the device. Synthesize
|
|
1123
|
+
# the hook response from the local verdict only.
|
|
1124
|
+
OK=$(echo "$VERDICT_JSON" | jq -r '.ok // true' 2>/dev/null)
|
|
1125
|
+
if [ "$OK" = "false" ]; then
|
|
1126
|
+
FIRST_REASON=$(echo "$VERDICT_JSON" | jq -r '.violations[0].reason // "policy violation"' 2>/dev/null)
|
|
1127
|
+
RULE_ID=$(echo "$VERDICT_JSON" | jq -r '.violations[0].rule_id // "local_violation"' 2>/dev/null)
|
|
1128
|
+
if [ "$IS_HEADLESS" = "1" ]; then DEC="deny"; else DEC="ask"; fi
|
|
1129
|
+
RESP=$(jq -n \\
|
|
1130
|
+
--arg dec "$DEC" \\
|
|
1131
|
+
--arg reason "[synkro] $RULE_ID: $FIRST_REASON" \\
|
|
1132
|
+
'{ hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: $dec, permissionDecisionReason: $reason, additionalContext: $reason }, reason: $reason }')
|
|
1133
|
+
else
|
|
1134
|
+
RESP=$(jq -n '{ hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "allow" }, reason: "" }')
|
|
1135
|
+
fi
|
|
1136
|
+
else
|
|
1137
|
+
LOCAL_BODY=$(jq -n \\
|
|
1138
|
+
--argjson verdict "$VERDICT_JSON" \\
|
|
1139
|
+
--arg file_path "$FILE_PATH" \\
|
|
1140
|
+
--arg tool_name "$TOOL_NAME" \\
|
|
1141
|
+
--arg content "$PROPOSED" \\
|
|
1142
|
+
--arg file_before "$FILE_BEFORE" \\
|
|
1143
|
+
--argjson diff "$DIFF_FIELD" \\
|
|
1144
|
+
--arg user_intent "$USER_INTENT" \\
|
|
1145
|
+
--argjson recent_actions "$RECENT_ACTIONS" \\
|
|
1146
|
+
--arg session_id "$SESSION_ID" \\
|
|
1147
|
+
--arg tool_use_id "$TOOL_USE_ID" \\
|
|
1148
|
+
--arg cwd "$CWD" \\
|
|
1149
|
+
--arg permission_mode "$PERMISSION_MODE" \\
|
|
1150
|
+
--arg headless_flag "$HEADLESS_FLAG" \\
|
|
1151
|
+
--arg repo "$GIT_REPO" \\
|
|
1152
|
+
'{
|
|
1153
|
+
verdict: $verdict,
|
|
1154
|
+
file_path: $file_path,
|
|
1155
|
+
tool_name: $tool_name,
|
|
1156
|
+
content: $content,
|
|
1157
|
+
file_before: (if ($file_before | length) > 0 then $file_before else null end),
|
|
1158
|
+
diff: $diff,
|
|
1159
|
+
user_intent: (if ($user_intent | length) > 0 then $user_intent else null end),
|
|
1160
|
+
recent_actions: $recent_actions,
|
|
1161
|
+
session_id: (if ($session_id | length) > 0 then $session_id else null end),
|
|
1162
|
+
tool_use_id: (if ($tool_use_id | length) > 0 then $tool_use_id else null end),
|
|
1163
|
+
cwd: (if ($cwd | length) > 0 then $cwd else null end),
|
|
1164
|
+
permission_mode: (if ($permission_mode | length) > 0 then $permission_mode else null end),
|
|
1165
|
+
headless: ($headless_flag == "1"),
|
|
1166
|
+
repo: (if ($repo | length) > 0 then $repo else null end)
|
|
1167
|
+
}')
|
|
1158
1168
|
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1169
|
+
RESP=$(curl -sS -X POST "\${GATEWAY_URL}/api/v1/precheck-edit/local-verdict" \\
|
|
1170
|
+
-H "Content-Type: application/json" \\
|
|
1171
|
+
-H "Authorization: Bearer $JWT" \\
|
|
1172
|
+
-d "$LOCAL_BODY" \\
|
|
1173
|
+
--max-time 5 2>/dev/null || echo "")
|
|
1174
|
+
|
|
1175
|
+
if echo "$RESP" | grep -qE '"detail":"Token has expired|"detail":"Invalid or expired token'; then
|
|
1176
|
+
if refresh_jwt; then
|
|
1177
|
+
RESP=$(curl -sS -X POST "\${GATEWAY_URL}/api/v1/precheck-edit/local-verdict" \\
|
|
1178
|
+
-H "Content-Type: application/json" \\
|
|
1179
|
+
-H "Authorization: Bearer $JWT" \\
|
|
1180
|
+
-d "$LOCAL_BODY" \\
|
|
1181
|
+
--max-time 5 2>/dev/null || echo "")
|
|
1182
|
+
fi
|
|
1166
1183
|
fi
|
|
1167
1184
|
fi
|
|
1168
1185
|
else
|
|
@@ -1402,32 +1419,57 @@ if [ -n "$SESSION_ID" ] && [ -n "$TOOL_USE_ID" ]; then
|
|
|
1402
1419
|
) &
|
|
1403
1420
|
fi
|
|
1404
1421
|
|
|
1405
|
-
# Resolve tier (cached 60 min)
|
|
1422
|
+
# Resolve tier + capture_depth (cached 60 min).
|
|
1406
1423
|
TIER_CACHE_FILE="$HOME/.synkro/.tier-cache-\${SYNKRO_USER_ID:-default}"
|
|
1424
|
+
CD_CACHE_FILE="\${TIER_CACHE_FILE}.cd"
|
|
1407
1425
|
SYNKRO_INFERENCE_TIER=""
|
|
1426
|
+
SYNKRO_CAPTURE_DEPTH=""
|
|
1408
1427
|
if find "$TIER_CACHE_FILE" -mmin -60 2>/dev/null | grep -q .; then
|
|
1409
1428
|
SYNKRO_INFERENCE_TIER=$(cat "$TIER_CACHE_FILE" 2>/dev/null || true)
|
|
1429
|
+
SYNKRO_CAPTURE_DEPTH=$(cat "$CD_CACHE_FILE" 2>/dev/null || true)
|
|
1410
1430
|
fi
|
|
1411
1431
|
if [ -z "$SYNKRO_INFERENCE_TIER" ]; then
|
|
1412
1432
|
ME_RESP=$(curl -sS "\${GATEWAY_URL}/api/v1/cli/me" -H "Authorization: Bearer $JWT" --max-time 2 2>/dev/null || echo "")
|
|
1413
1433
|
if [ -n "$ME_RESP" ]; then
|
|
1414
1434
|
SYNKRO_INFERENCE_TIER=$(echo "$ME_RESP" | jq -r '.tier // empty' 2>/dev/null || true)
|
|
1415
1435
|
[ -n "$SYNKRO_INFERENCE_TIER" ] && printf '%s' "$SYNKRO_INFERENCE_TIER" > "$TIER_CACHE_FILE" 2>/dev/null || true
|
|
1436
|
+
SYNKRO_CAPTURE_DEPTH=$(echo "$ME_RESP" | jq -r '.capture_depth // empty' 2>/dev/null || true)
|
|
1437
|
+
[ -n "$SYNKRO_CAPTURE_DEPTH" ] && printf '%s' "$SYNKRO_CAPTURE_DEPTH" > "$CD_CACHE_FILE" 2>/dev/null || true
|
|
1416
1438
|
fi
|
|
1417
1439
|
fi
|
|
1418
1440
|
SYNKRO_INFERENCE_TIER="\${SYNKRO_INFERENCE_TIER:-fast}"
|
|
1441
|
+
SYNKRO_CAPTURE_DEPTH="\${SYNKRO_CAPTURE_DEPTH:-full}"
|
|
1442
|
+
|
|
1443
|
+
USE_LOCAL=false
|
|
1444
|
+
if [ "$SYNKRO_CAPTURE_DEPTH" = "local_only" ] && command -v claude >/dev/null 2>&1; then
|
|
1445
|
+
USE_LOCAL=true
|
|
1446
|
+
elif [ "$SYNKRO_INFERENCE_TIER" = "free" ] && command -v claude >/dev/null 2>&1; then
|
|
1447
|
+
USE_LOCAL=true
|
|
1448
|
+
fi
|
|
1419
1449
|
|
|
1420
|
-
if [ "$
|
|
1421
|
-
# \u2500\u2500\u2500
|
|
1450
|
+
if [ "$USE_LOCAL" = "true" ]; then
|
|
1451
|
+
# \u2500\u2500\u2500 LOCAL GRADING: grade via the persistent claude daemon (mode=edit). \u2500\u2500\u2500
|
|
1422
1452
|
|
|
1423
|
-
#
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1453
|
+
# In local_only: GET all rules (no content sent), cache 1h. Otherwise POST with content.
|
|
1454
|
+
RULES_CACHE="$HOME/.synkro/.rules-cache-edit-capture"
|
|
1455
|
+
if [ "$SYNKRO_CAPTURE_DEPTH" = "local_only" ]; then
|
|
1456
|
+
if find "$RULES_CACHE" -mmin -60 2>/dev/null | grep -q .; then
|
|
1457
|
+
ORG_RULES=$(cat "$RULES_CACHE" 2>/dev/null || echo "[]")
|
|
1458
|
+
else
|
|
1459
|
+
ORG_RULES=$(curl -sS "\${GATEWAY_URL}/api/v1/cli/pr-rules" \\
|
|
1460
|
+
-H "Authorization: Bearer $JWT" --max-time 2 2>/dev/null \\
|
|
1461
|
+
| jq -c '[.rules[]? | {rule_id, text, severity, category}]' 2>/dev/null || echo "[]")
|
|
1462
|
+
[ -n "$ORG_RULES" ] && [ "$ORG_RULES" != "null" ] && printf '%s' "$ORG_RULES" > "$RULES_CACHE" 2>/dev/null || true
|
|
1463
|
+
fi
|
|
1464
|
+
else
|
|
1465
|
+
ORG_RULES=$(printf '%s' "$FILE_CONTENT" | head -c 8000 \\
|
|
1466
|
+
| jq -Rs '{content: .}' \\
|
|
1467
|
+
| curl -sS "\${GATEWAY_URL}/api/v1/cli/pr-rules?top_k=20" \\
|
|
1468
|
+
-X POST -H "Content-Type: application/json" \\
|
|
1469
|
+
-H "Authorization: Bearer $JWT" \\
|
|
1470
|
+
-d @- --max-time 2 2>/dev/null \\
|
|
1471
|
+
| jq -c '[.rules[]? | {rule_id, text, severity, category}]' 2>/dev/null || echo "[]")
|
|
1472
|
+
fi
|
|
1431
1473
|
if [ -z "$ORG_RULES" ] || [ "$ORG_RULES" = "null" ]; then ORG_RULES="[]"; fi
|
|
1432
1474
|
|
|
1433
1475
|
GRADER_PROMPT_FILE=$(mktemp -t synkro-edit-capture.XXXXXX)
|
|
@@ -1701,6 +1743,12 @@ CREDS_PATH="\${SYNKRO_CREDENTIALS_PATH:-$HOME/.synkro/credentials.json}"
|
|
|
1701
1743
|
|
|
1702
1744
|
if [ ! -f "$CREDS_PATH" ]; then echo '{}'; exit 0; fi
|
|
1703
1745
|
if [ "\${SYNKRO_TRANSCRIPT_CONSENT:-yes}" = "no" ]; then echo '{}'; exit 0; fi
|
|
1746
|
+
|
|
1747
|
+
# Hard-skip in local_only privacy mode \u2014 conversation content must never leave the device.
|
|
1748
|
+
CD_CACHE_FILE="$HOME/.synkro/.tier-cache-\${SYNKRO_USER_ID:-default}.cd"
|
|
1749
|
+
SYNKRO_CAPTURE_DEPTH=$(cat "$CD_CACHE_FILE" 2>/dev/null || echo "full")
|
|
1750
|
+
if [ "$SYNKRO_CAPTURE_DEPTH" = "local_only" ]; then echo '{}'; exit 0; fi
|
|
1751
|
+
|
|
1704
1752
|
JWT=$(jq -r '.access_token // empty' "$CREDS_PATH" 2>/dev/null)
|
|
1705
1753
|
if [ -z "$JWT" ]; then echo '{}'; exit 0; fi
|
|
1706
1754
|
|
|
@@ -3554,7 +3602,7 @@ function writeConfigEnv(opts) {
|
|
|
3554
3602
|
`SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
|
|
3555
3603
|
`SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
|
|
3556
3604
|
`SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
|
|
3557
|
-
`SYNKRO_VERSION=${shellQuoteSingle("1.3.
|
|
3605
|
+
`SYNKRO_VERSION=${shellQuoteSingle("1.3.32")}`
|
|
3558
3606
|
];
|
|
3559
3607
|
if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
|
|
3560
3608
|
if (safeOrgId) lines.push(`SYNKRO_ORG_ID=${shellQuoteSingle(safeOrgId)}`);
|