@synkro-sh/cli 1.4.36 → 1.4.38
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 +119 -83
- package/dist/bootstrap.js.map +1 -1
- package/package.json +1 -1
package/dist/bootstrap.js
CHANGED
|
@@ -198,20 +198,18 @@ function installCCHooks(settingsPath, config) {
|
|
|
198
198
|
],
|
|
199
199
|
[SYNKRO_MARKER]: true
|
|
200
200
|
});
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
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) {
|
|
@@ -510,16 +508,25 @@ synkro_channel_up() {
|
|
|
510
508
|
(exec 3<>/dev/tcp/127.0.0.1/\${SYNKRO_CHANNEL_PORT:-8929}) 2>/dev/null && exec 3<&- 3>&-
|
|
511
509
|
}
|
|
512
510
|
|
|
513
|
-
# Fetch hook config. Sets SYNKRO_CAPTURE_DEPTH, SYNKRO_TIER, SYNKRO_RULES.
|
|
511
|
+
# Fetch hook config. Sets SYNKRO_CAPTURE_DEPTH, SYNKRO_TIER, SYNKRO_RULES, SYNKRO_SILENT, SYNKRO_POLICY_NAME.
|
|
514
512
|
synkro_load_config() {
|
|
515
513
|
local resp
|
|
516
514
|
resp=$(curl -sS "\${GATEWAY_URL}/api/v1/hook/config\${1:+?$1}" -H "Authorization: Bearer $JWT" --max-time 4 2>/dev/null || echo "")
|
|
517
515
|
if [ -z "$resp" ]; then return; fi
|
|
518
516
|
SYNKRO_CAPTURE_DEPTH=$(echo "$resp" | jq -r '.capture_depth // "local_only"' 2>/dev/null)
|
|
519
517
|
SYNKRO_TIER=$(echo "$resp" | jq -r '.tier // "standard"' 2>/dev/null)
|
|
518
|
+
SYNKRO_SILENT=$(echo "$resp" | jq -r '.silent_mode // false' 2>/dev/null)
|
|
519
|
+
SYNKRO_POLICY_NAME=$(echo "$resp" | jq -r '.active_policy_name // empty' 2>/dev/null)
|
|
520
520
|
SYNKRO_RULES=$(echo "$resp" | jq -c '[.rules[]? | select(.hook_stage == "pre" or .hook_stage == "both" or .hook_stage == null) | {rule_id,text,severity,category,mode}]' 2>/dev/null || echo "[]")
|
|
521
521
|
}
|
|
522
522
|
|
|
523
|
+
# Build the tag prefix for system messages: [synkro] or [synkro:PolicyName] or [synkro:silent]
|
|
524
|
+
synkro_tag() {
|
|
525
|
+
if [ "$SYNKRO_SILENT" = "true" ]; then echo "[synkro:silent]"; return; fi
|
|
526
|
+
if [ -n "\${SYNKRO_POLICY_NAME:-}" ]; then echo "[synkro:\${SYNKRO_POLICY_NAME}]"; return; fi
|
|
527
|
+
echo "[synkro]"
|
|
528
|
+
}
|
|
529
|
+
|
|
523
530
|
# Decide routing: "local" (grade on device) or "cloud" (POST to server)
|
|
524
531
|
synkro_route() {
|
|
525
532
|
[ "$SYNKRO_CAPTURE_DEPTH" = "local_only" ] && echo "local" && return
|
|
@@ -739,6 +746,20 @@ IS_HEADLESS="\${SYNKRO_HEADLESS:-0}"
|
|
|
739
746
|
case "$PERMISSION_MODE" in acceptEdits|bypassPermissions|plan|auto) IS_HEADLESS="1" ;; esac
|
|
740
747
|
|
|
741
748
|
synkro_load_config
|
|
749
|
+
TAG=$(synkro_tag)
|
|
750
|
+
|
|
751
|
+
if [ "$SYNKRO_SILENT" = "true" ]; then
|
|
752
|
+
jq -n --arg m "$TAG bashGuard \u2192 skipped (silent mode)" '{systemMessage: $m}'
|
|
753
|
+
exit 0
|
|
754
|
+
fi
|
|
755
|
+
|
|
756
|
+
# Pre-grade consent check: skip grading if user already approved this command in this session
|
|
757
|
+
CMD_HASH=$(printf '%s' "$COMMAND" | shasum -a 256 | cut -c1-16)
|
|
758
|
+
if [ -n "$SESSION_ID" ] && [ -n "$CMD_HASH" ] && synkro_consent_has_active "$SESSION_ID" "$CMD_HASH"; then
|
|
759
|
+
jq -n --arg m "$TAG bashGuard \u2192 pass (previously approved)" '{systemMessage: $m}'
|
|
760
|
+
exit 0
|
|
761
|
+
fi
|
|
762
|
+
|
|
742
763
|
ROUTE=$(synkro_route)
|
|
743
764
|
|
|
744
765
|
if [ "$ROUTE" = "local" ]; then
|
|
@@ -749,7 +770,7 @@ if [ "$ROUTE" = "local" ]; then
|
|
|
749
770
|
|
|
750
771
|
CC_RESP=$(synkro_local_grade bash < "$GRADER_FILE" 2>&1)
|
|
751
772
|
if [ $? -ne 0 ]; then
|
|
752
|
-
jq -n --arg m "
|
|
773
|
+
jq -n --arg m "$TAG bashGuard \u2192 pass: local grader unavailable (run synkro local-cc start)" '{systemMessage: $m}'
|
|
753
774
|
exit 0
|
|
754
775
|
fi
|
|
755
776
|
synkro_parse_local_verdict "$CC_RESP"
|
|
@@ -761,31 +782,20 @@ if [ "$ROUTE" = "local" ]; then
|
|
|
761
782
|
if [ "$LOCAL_OK" = "false" ]; then
|
|
762
783
|
RULE_MODE="\${LOCAL_RULE_MODE:-$(synkro_rule_mode "\${LOCAL_RULE_ID}")}"
|
|
763
784
|
if [ "$RULE_MODE" = "audit" ]; then
|
|
764
|
-
REASON="
|
|
785
|
+
REASON="$TAG bashGuard \u2192 warning\${LOCAL_RULE_ID:+ ($LOCAL_RULE_ID)}: \${LOCAL_REASON:-policy violation}"
|
|
765
786
|
jq -n --arg m "$REASON" '{systemMessage: $m}'
|
|
766
787
|
synkro_dispatch_capture "bash" "warning" "\${LOCAL_SEV}" "\${LOCAL_CAT}" "$TOOL_NAME" "$GIT_REPO" "$SESSION_ID" \\
|
|
767
788
|
"$COMMAND" "$LOCAL_REASON" "\${SYNKRO_RULES:-[]}" "$VIOLATED_JSON" "\${RECENT_USER_MESSAGES:-[]}"
|
|
768
789
|
else
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
else
|
|
776
|
-
if [ -n "$SESSION_ID" ] && synkro_consent_has_consumed "$SESSION_ID" "$CMD_HASH"; then
|
|
777
|
-
synkro_consent_clear_consumed "$SESSION_ID" "$CMD_HASH"
|
|
778
|
-
fi
|
|
779
|
-
if [ "$IS_HEADLESS" = "1" ]; then DEC="deny"; else DEC="ask"; fi
|
|
780
|
-
REASON="[synkro:local] bashGuard \u2192 block\${LOCAL_RULE_ID:+ ($LOCAL_RULE_ID)}: \${LOCAL_REASON:-policy violation}"
|
|
781
|
-
jq -n --arg dec "$DEC" --arg reason "$REASON" --arg ctx "$REASON" \\
|
|
782
|
-
'{systemMessage:$reason,hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:$dec,permissionDecisionReason:$reason,additionalContext:$ctx}}'
|
|
783
|
-
synkro_dispatch_capture "bash" "block" "\${LOCAL_SEV}" "\${LOCAL_CAT}" "$TOOL_NAME" "$GIT_REPO" "$SESSION_ID" \\
|
|
784
|
-
"$COMMAND" "$LOCAL_REASON" "\${SYNKRO_RULES:-[]}" "$VIOLATED_JSON" "\${RECENT_USER_MESSAGES:-[]}"
|
|
785
|
-
fi
|
|
790
|
+
if [ "$IS_HEADLESS" = "1" ]; then DEC="deny"; else DEC="ask"; fi
|
|
791
|
+
REASON="$TAG bashGuard \u2192 block\${LOCAL_RULE_ID:+ ($LOCAL_RULE_ID)}: \${LOCAL_REASON:-policy violation}"
|
|
792
|
+
jq -n --arg dec "$DEC" --arg reason "$REASON" --arg ctx "$REASON" \\
|
|
793
|
+
'{systemMessage:$reason,hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:$dec,permissionDecisionReason:$reason,additionalContext:$ctx}}'
|
|
794
|
+
synkro_dispatch_capture "bash" "block" "\${LOCAL_SEV}" "\${LOCAL_CAT}" "$TOOL_NAME" "$GIT_REPO" "$SESSION_ID" \\
|
|
795
|
+
"$COMMAND" "$LOCAL_REASON" "\${SYNKRO_RULES:-[]}" "$VIOLATED_JSON" "\${RECENT_USER_MESSAGES:-[]}"
|
|
786
796
|
fi
|
|
787
797
|
else
|
|
788
|
-
jq -n --arg m "
|
|
798
|
+
jq -n --arg m "$TAG bashGuard \u2192 pass: \${LOCAL_REASON:-no policy violations detected}" '{systemMessage: $m}'
|
|
789
799
|
synkro_dispatch_capture "bash" "pass" "audit" "\${LOCAL_CAT:-trivial_utility}" "$TOOL_NAME" "$GIT_REPO" "$SESSION_ID" \\
|
|
790
800
|
"$COMMAND" "$LOCAL_REASON" "\${SYNKRO_RULES:-[]}" "[]" "\${RECENT_USER_MESSAGES:-[]}"
|
|
791
801
|
fi
|
|
@@ -940,6 +950,13 @@ if [ -n "$TRANSCRIPT_PATH" ] && [ -f "$TRANSCRIPT_PATH" ]; then
|
|
|
940
950
|
fi
|
|
941
951
|
|
|
942
952
|
synkro_load_config
|
|
953
|
+
TAG=$(synkro_tag)
|
|
954
|
+
|
|
955
|
+
if [ "$SYNKRO_SILENT" = "true" ]; then
|
|
956
|
+
jq -n --arg m "$TAG editGuard \u2192 skipped (silent mode)" '{systemMessage: $m}'
|
|
957
|
+
exit 0
|
|
958
|
+
fi
|
|
959
|
+
|
|
943
960
|
ROUTE=$(synkro_route)
|
|
944
961
|
|
|
945
962
|
if [ "$ROUTE" = "local" ]; then
|
|
@@ -950,7 +967,7 @@ if [ "$ROUTE" = "local" ]; then
|
|
|
950
967
|
|
|
951
968
|
CC_RESP=$(synkro_local_grade edit < "$GRADER_FILE" 2>&1)
|
|
952
969
|
if [ $? -ne 0 ]; then
|
|
953
|
-
jq -n --arg m "
|
|
970
|
+
jq -n --arg m "$TAG editGuard \u2192 pass: local grader unavailable (run synkro local-cc start)" '{systemMessage: $m}'
|
|
954
971
|
exit 0
|
|
955
972
|
fi
|
|
956
973
|
synkro_parse_local_verdict "$CC_RESP"
|
|
@@ -963,20 +980,20 @@ if [ "$ROUTE" = "local" ]; then
|
|
|
963
980
|
if [ "$LOCAL_OK" = "false" ]; then
|
|
964
981
|
RULE_MODE="\${LOCAL_RULE_MODE:-$(synkro_rule_mode "\${LOCAL_RULE_ID}")}"
|
|
965
982
|
if [ "$RULE_MODE" = "audit" ]; then
|
|
966
|
-
REASON="
|
|
983
|
+
REASON="$TAG editGuard $FILE_SHORT \u2192 warning\${LOCAL_RULE_ID:+ ($LOCAL_RULE_ID)}: \${LOCAL_REASON:-policy violation}"
|
|
967
984
|
jq -n --arg m "$REASON" '{systemMessage: $m}'
|
|
968
985
|
synkro_dispatch_capture "edit" "warning" "\${LOCAL_SEV}" "\${LOCAL_CAT}" "$TOOL_NAME" "$GIT_REPO" "$SESSION_ID" \\
|
|
969
986
|
"$EDIT_CONTENT" "$LOCAL_REASON" "\${SYNKRO_RULES:-[]}" "$VIOLATED_JSON" "[]"
|
|
970
987
|
else
|
|
971
988
|
if [ "$IS_HEADLESS" = "1" ]; then DEC="deny"; else DEC="ask"; fi
|
|
972
|
-
REASON="
|
|
989
|
+
REASON="$TAG editGuard $FILE_SHORT \u2192 block\${LOCAL_RULE_ID:+ ($LOCAL_RULE_ID)}: \${LOCAL_REASON:-policy violation}"
|
|
973
990
|
jq -n --arg dec "$DEC" --arg reason "$REASON" --arg ctx "$REASON" \\
|
|
974
991
|
'{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:$dec,permissionDecisionReason:$reason,additionalContext:$ctx}}'
|
|
975
992
|
synkro_dispatch_capture "edit" "block" "\${LOCAL_SEV}" "\${LOCAL_CAT}" "$TOOL_NAME" "$GIT_REPO" "$SESSION_ID" \\
|
|
976
993
|
"$EDIT_CONTENT" "$LOCAL_REASON" "\${SYNKRO_RULES:-[]}" "$VIOLATED_JSON" "[]"
|
|
977
994
|
fi
|
|
978
995
|
else
|
|
979
|
-
jq -n --arg m "
|
|
996
|
+
jq -n --arg m "$TAG editGuard $FILE_SHORT \u2192 pass: \${LOCAL_REASON:-no policy violations detected}" '{systemMessage: $m}'
|
|
980
997
|
synkro_dispatch_capture "edit" "pass" "audit" "\${LOCAL_CAT:-trivial_edit}" "$TOOL_NAME" "$GIT_REPO" "$SESSION_ID" \\
|
|
981
998
|
"$EDIT_CONTENT" "$LOCAL_REASON" "\${SYNKRO_RULES:-[]}" "[]" "[]"
|
|
982
999
|
fi
|
|
@@ -1101,6 +1118,12 @@ while [ "$_PKG_DIR" != "/" ]; do
|
|
|
1101
1118
|
done
|
|
1102
1119
|
|
|
1103
1120
|
synkro_load_config
|
|
1121
|
+
TAG=$(synkro_tag)
|
|
1122
|
+
|
|
1123
|
+
if [ "$SYNKRO_SILENT" = "true" ]; then
|
|
1124
|
+
echo '{}'; exit 0
|
|
1125
|
+
fi
|
|
1126
|
+
|
|
1104
1127
|
ROUTE=$(synkro_route)
|
|
1105
1128
|
|
|
1106
1129
|
if [ "$ROUTE" = "local" ]; then
|
|
@@ -1122,18 +1145,18 @@ if [ "$ROUTE" = "local" ]; then
|
|
|
1122
1145
|
if [ "$LOCAL_OK" = "false" ]; then
|
|
1123
1146
|
RULE_MODE="\${LOCAL_RULE_MODE:-$(synkro_rule_mode "\${LOCAL_RULE_ID}")}"
|
|
1124
1147
|
if [ "$RULE_MODE" = "audit" ]; then
|
|
1125
|
-
REASON="
|
|
1148
|
+
REASON="$TAG editScan $BASENAME \u2192 warning\${LOCAL_RULE_ID:+ ($LOCAL_RULE_ID)}: \${LOCAL_REASON:-policy violation}"
|
|
1126
1149
|
jq -n --arg m "$REASON" '{systemMessage: $m}'
|
|
1127
1150
|
synkro_dispatch_capture "edit_scan" "warning" "\${LOCAL_SEV}" "\${LOCAL_CAT}" "$TOOL_NAME" "$GIT_REPO" "$SESSION_ID" \\
|
|
1128
1151
|
"$SCAN_CONTENT" "$LOCAL_REASON" "\${SYNKRO_RULES:-[]}" "$SCAN_VIOLATED" "[]"
|
|
1129
1152
|
else
|
|
1130
|
-
REASON="
|
|
1153
|
+
REASON="$TAG editScan $BASENAME \u2192 block: \${LOCAL_REASON:-policy violation}"
|
|
1131
1154
|
jq -n --arg m "$REASON" '{systemMessage: $m, additionalContext: $m}'
|
|
1132
1155
|
synkro_dispatch_capture "edit_scan" "block" "\${LOCAL_SEV}" "\${LOCAL_CAT}" "$TOOL_NAME" "$GIT_REPO" "$SESSION_ID" \\
|
|
1133
1156
|
"$SCAN_CONTENT" "$LOCAL_REASON" "\${SYNKRO_RULES:-[]}" "$SCAN_VIOLATED" "[]"
|
|
1134
1157
|
fi
|
|
1135
1158
|
else
|
|
1136
|
-
jq -n --arg m "
|
|
1159
|
+
jq -n --arg m "$TAG editScan $BASENAME \u2192 pass: \${LOCAL_REASON:-no policy violations detected}" '{systemMessage: $m}'
|
|
1137
1160
|
synkro_dispatch_capture "edit_scan" "pass" "audit" "\${LOCAL_CAT:-trivial_edit}" "$TOOL_NAME" "$GIT_REPO" "$SESSION_ID" \\
|
|
1138
1161
|
"$SCAN_CONTENT" "$LOCAL_REASON" "\${SYNKRO_RULES:-[]}" "[]" "[]"
|
|
1139
1162
|
fi
|
|
@@ -1207,6 +1230,13 @@ PLAN_SHORT=$(printf '%s' "$PLAN" | head -c 80)
|
|
|
1207
1230
|
synkro_log "planReview checking: $PLAN_SHORT..."
|
|
1208
1231
|
|
|
1209
1232
|
synkro_load_config
|
|
1233
|
+
TAG=$(synkro_tag)
|
|
1234
|
+
|
|
1235
|
+
if [ "$SYNKRO_SILENT" = "true" ]; then
|
|
1236
|
+
jq -n --arg m "$TAG planReview \u2192 skipped (silent mode)" '{systemMessage: $m}'
|
|
1237
|
+
exit 0
|
|
1238
|
+
fi
|
|
1239
|
+
|
|
1210
1240
|
ROUTE=$(synkro_route)
|
|
1211
1241
|
|
|
1212
1242
|
if [ "$ROUTE" = "local" ]; then
|
|
@@ -1227,12 +1257,12 @@ if [ "$ROUTE" = "local" ]; then
|
|
|
1227
1257
|
if [ "$LOCAL_OK" = "false" ]; then
|
|
1228
1258
|
VCOUNT=$(printf '%s' "$CC_RESP" | grep -c '<violation>' 2>/dev/null || echo "0")
|
|
1229
1259
|
[ "$VCOUNT" = "0" ] && VCOUNT="1"
|
|
1230
|
-
MSG="
|
|
1260
|
+
MSG="$TAG planReview \u2192 \${VCOUNT} rule(s) relevant\${LOCAL_RULE_ID:+ (first: $LOCAL_RULE_ID)}: \${LOCAL_REASON:-check org rules during implementation}"
|
|
1231
1261
|
jq -n --arg m "$MSG" '{systemMessage: $m}'
|
|
1232
1262
|
synkro_dispatch_capture "plan_review" "advisory" "\${LOCAL_SEV}" "\${LOCAL_CAT}" "ExitPlanMode" "$GIT_REPO" "$SESSION_ID" \\
|
|
1233
1263
|
"$PLAN_CONTENT" "$LOCAL_REASON" "\${SYNKRO_RULES:-[]}" "$PLAN_VIOLATED" "[]"
|
|
1234
1264
|
else
|
|
1235
|
-
jq -n --arg m "
|
|
1265
|
+
jq -n --arg m "$TAG planReview \u2192 clean: \${LOCAL_REASON:-no relevant org rules for this plan}" '{systemMessage: $m}'
|
|
1236
1266
|
synkro_dispatch_capture "plan_review" "clean" "audit" "\${LOCAL_CAT:-general}" "ExitPlanMode" "$GIT_REPO" "$SESSION_ID" \\
|
|
1237
1267
|
"$PLAN_CONTENT" "$LOCAL_REASON" "\${SYNKRO_RULES:-[]}" "[]" "[]"
|
|
1238
1268
|
fi
|
|
@@ -1273,7 +1303,7 @@ fi
|
|
|
1273
1303
|
HR=$(echo "$RESP" | jq -c '.hook_response')
|
|
1274
1304
|
if echo "$HR" | jq -e '.hookSpecificOutput.permissionDecision' >/dev/null 2>&1; then
|
|
1275
1305
|
REASON=$(echo "$HR" | jq -r '.hookSpecificOutput.permissionDecisionReason // "check org rules"' 2>/dev/null)
|
|
1276
|
-
jq -n --arg m "
|
|
1306
|
+
jq -n --arg m "$TAG planReview \u2192 advisory: $REASON" '{systemMessage: $m}'
|
|
1277
1307
|
else
|
|
1278
1308
|
echo "$HR"
|
|
1279
1309
|
fi
|
|
@@ -1341,10 +1371,12 @@ OPEN=$(echo "$RESP" | jq -r '.open // 0' 2>/dev/null)
|
|
|
1341
1371
|
|
|
1342
1372
|
if [ "\${EDITS:-0}" = "0" ] || [ -z "$EDITS" ]; then echo '{}'; exit 0; fi
|
|
1343
1373
|
|
|
1374
|
+
synkro_load_config
|
|
1375
|
+
TAG=$(synkro_tag)
|
|
1344
1376
|
if [ "\${FINDINGS:-0}" = "0" ] || [ -z "$FINDINGS" ]; then
|
|
1345
|
-
SYS_MSG="
|
|
1377
|
+
SYS_MSG="$TAG stop \u2192 0 issues across \${EDITS} edit(s), session complete"
|
|
1346
1378
|
else
|
|
1347
|
-
SYS_MSG="
|
|
1379
|
+
SYS_MSG="$TAG stop \u2192 \${FINDINGS} finding(s): \${AUTO_FIXED} auto-fixed, \${OPEN} open"
|
|
1348
1380
|
fi
|
|
1349
1381
|
|
|
1350
1382
|
jq -n --arg m "$SYS_MSG" '{systemMessage: $m}'
|
|
@@ -1358,11 +1390,30 @@ JWT=$(synkro_load_jwt)
|
|
|
1358
1390
|
|
|
1359
1391
|
# Route preamble
|
|
1360
1392
|
SYNKRO_PORT="\${SYNKRO_CHANNEL_PORT:-8929}"
|
|
1393
|
+
PAYLOAD=$(cat)
|
|
1394
|
+
CWD=$(echo "$PAYLOAD" | jq -r '.cwd // empty' 2>/dev/null)
|
|
1395
|
+
SESSION_ID=$(echo "$PAYLOAD" | jq -r '.session_id // empty' 2>/dev/null)
|
|
1396
|
+
GIT_REPO=$(synkro_detect_repo "\${CWD:-.}")
|
|
1397
|
+
|
|
1398
|
+
RESP=""
|
|
1399
|
+
if [ -n "$JWT" ]; then
|
|
1400
|
+
RESP=$(curl -sS -G "\${GATEWAY_URL}/api/v1/hook/config" \\
|
|
1401
|
+
--data-urlencode "session_id=\${SESSION_ID:-}" \\
|
|
1402
|
+
--data-urlencode "repo=\${GIT_REPO:-}" \\
|
|
1403
|
+
-H "Authorization: Bearer $JWT" --max-time 3 2>/dev/null || echo "")
|
|
1404
|
+
if [ -n "$RESP" ]; then
|
|
1405
|
+
SYNKRO_SILENT=$(echo "$RESP" | jq -r '.silent_mode // false' 2>/dev/null)
|
|
1406
|
+
SYNKRO_POLICY_NAME=$(echo "$RESP" | jq -r '.active_policy_name // empty' 2>/dev/null)
|
|
1407
|
+
fi
|
|
1408
|
+
fi
|
|
1409
|
+
|
|
1410
|
+
TAG=$(synkro_tag)
|
|
1411
|
+
|
|
1361
1412
|
if (exec 3<>/dev/tcp/127.0.0.1/"$SYNKRO_PORT") 2>/dev/null; then
|
|
1362
1413
|
exec 3<&- 3>&- 2>/dev/null || true
|
|
1363
|
-
ROUTE_LINE="
|
|
1414
|
+
ROUTE_LINE="$TAG inference: local-cc (channel reachable on 127.0.0.1:$SYNKRO_PORT)"
|
|
1364
1415
|
else
|
|
1365
|
-
ROUTE_LINE="
|
|
1416
|
+
ROUTE_LINE="$TAG inference: cloud (local-cc channel not reachable)"
|
|
1366
1417
|
fi
|
|
1367
1418
|
|
|
1368
1419
|
if [ -z "$JWT" ]; then
|
|
@@ -1370,16 +1421,6 @@ if [ -z "$JWT" ]; then
|
|
|
1370
1421
|
exit 0
|
|
1371
1422
|
fi
|
|
1372
1423
|
|
|
1373
|
-
PAYLOAD=$(cat)
|
|
1374
|
-
CWD=$(echo "$PAYLOAD" | jq -r '.cwd // empty' 2>/dev/null)
|
|
1375
|
-
SESSION_ID=$(echo "$PAYLOAD" | jq -r '.session_id // empty' 2>/dev/null)
|
|
1376
|
-
GIT_REPO=$(synkro_detect_repo "\${CWD:-.}")
|
|
1377
|
-
|
|
1378
|
-
RESP=$(curl -sS -G "\${GATEWAY_URL}/api/v1/hook/config" \\
|
|
1379
|
-
--data-urlencode "session_id=\${SESSION_ID:-}" \\
|
|
1380
|
-
--data-urlencode "repo=\${GIT_REPO:-}" \\
|
|
1381
|
-
-H "Authorization: Bearer $JWT" --max-time 3 2>/dev/null || echo "")
|
|
1382
|
-
|
|
1383
1424
|
OPEN=0
|
|
1384
1425
|
if [ -n "$RESP" ]; then
|
|
1385
1426
|
OPEN=$(echo "$RESP" | jq -r '.session_context.open_findings // 0' 2>/dev/null)
|
|
@@ -1389,9 +1430,9 @@ if [ "$OPEN" = "0" ] || [ -z "$OPEN" ]; then
|
|
|
1389
1430
|
jq -n --arg m "$ROUTE_LINE" '{systemMessage: $m}'
|
|
1390
1431
|
else
|
|
1391
1432
|
if [ "$OPEN" = "1" ]; then
|
|
1392
|
-
SYS_MSG="$ROUTE_LINE"$'\\n'"
|
|
1433
|
+
SYS_MSG="$ROUTE_LINE"$'\\n'"$TAG session start \u2192 1 open finding in this repo from a prior session."
|
|
1393
1434
|
else
|
|
1394
|
-
SYS_MSG="$ROUTE_LINE"$'\\n'"
|
|
1435
|
+
SYS_MSG="$ROUTE_LINE"$'\\n'"$TAG session start \u2192 \${OPEN} open findings in this repo from prior sessions."
|
|
1395
1436
|
fi
|
|
1396
1437
|
jq -n --arg m "$SYS_MSG" '{systemMessage: $m}'
|
|
1397
1438
|
fi
|
|
@@ -1427,13 +1468,10 @@ BODY=$(jq -n --arg sid "$SESSION_ID" --arg tid "$TOOL_USE_ID" \\
|
|
|
1427
1468
|
# Local consent tracking: command ran = user consented
|
|
1428
1469
|
# On success \u2192 consume (next attempt blocks fresh)
|
|
1429
1470
|
# On failure \u2192 grant active (retry allowed)
|
|
1471
|
+
# Command ran (user approved it) \u2014 grant persistent consent for this session
|
|
1430
1472
|
if [ -n "$CMD_HASH" ] && [ -n "$SESSION_ID" ]; then
|
|
1431
|
-
if
|
|
1432
|
-
|
|
1433
|
-
else
|
|
1434
|
-
if ! synkro_consent_has_active "$SESSION_ID" "$CMD_HASH"; then
|
|
1435
|
-
synkro_consent_grant "$SESSION_ID" "$CMD_HASH"
|
|
1436
|
-
fi
|
|
1473
|
+
if ! synkro_consent_has_active "$SESSION_ID" "$CMD_HASH"; then
|
|
1474
|
+
synkro_consent_grant "$SESSION_ID" "$CMD_HASH"
|
|
1437
1475
|
fi
|
|
1438
1476
|
fi
|
|
1439
1477
|
|
|
@@ -1460,18 +1498,14 @@ if [ -z "$SESSION_ID" ] || [ -z "$TRANSCRIPT_PATH" ] || [ ! -f "$TRANSCRIPT_PATH
|
|
|
1460
1498
|
echo '{}'; exit 0
|
|
1461
1499
|
fi
|
|
1462
1500
|
|
|
1463
|
-
# Usage telemetry \u2014
|
|
1501
|
+
# Usage telemetry \u2014 last turn only (metadata, ungated by privacy/consent)
|
|
1464
1502
|
_LAST_ASST=$(grep '"type":"assistant"' "$TRANSCRIPT_PATH" 2>/dev/null | tail -1)
|
|
1465
1503
|
if [ -n "$_LAST_ASST" ]; then
|
|
1466
1504
|
_CC_MODEL=$(echo "$_LAST_ASST" | jq -r '.message.model // empty' 2>/dev/null)
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
_TI=$(echo "$_TOTALS" | jq -r '.in // 0')
|
|
1472
|
-
_TO=$(echo "$_TOTALS" | jq -r '.out // 0')
|
|
1473
|
-
_TCW=$(echo "$_TOTALS" | jq -r '.cw // 0')
|
|
1474
|
-
_TCR=$(echo "$_TOTALS" | jq -r '.cr // 0')
|
|
1505
|
+
_TI=$(echo "$_LAST_ASST" | jq -r '.message.usage.input_tokens // 0' 2>/dev/null)
|
|
1506
|
+
_TO=$(echo "$_LAST_ASST" | jq -r '.message.usage.output_tokens // 0' 2>/dev/null)
|
|
1507
|
+
_TCW=$(echo "$_LAST_ASST" | jq -r '.message.usage.cache_creation_input_tokens // 0' 2>/dev/null)
|
|
1508
|
+
_TCR=$(echo "$_LAST_ASST" | jq -r '.message.usage.cache_read_input_tokens // 0' 2>/dev/null)
|
|
1475
1509
|
if [ "\${_TI:-0}" != "0" ] || [ "\${_TO:-0}" != "0" ]; then
|
|
1476
1510
|
(
|
|
1477
1511
|
_USAGE="{\\"input_tokens\\":$_TI,\\"output_tokens\\":$_TO,\\"cache_creation_input_tokens\\":$_TCW,\\"cache_read_input_tokens\\":$_TCR}"
|
|
@@ -1568,6 +1602,9 @@ GIT_REPO=$(synkro_detect_repo "\${CWD:-.}")
|
|
|
1568
1602
|
CMD_SHORT=$(printf '%s' "$COMMAND" | head -c 80)
|
|
1569
1603
|
synkro_log "bashGuard checking: $CMD_SHORT"
|
|
1570
1604
|
|
|
1605
|
+
synkro_load_config
|
|
1606
|
+
if [ "$SYNKRO_SILENT" = "true" ]; then echo '{}'; exit 0; fi
|
|
1607
|
+
|
|
1571
1608
|
BODY=$(jq -n \\
|
|
1572
1609
|
--arg cmd "$COMMAND" \\
|
|
1573
1610
|
--arg session_id "$SESSION_ID" \\
|
|
@@ -1621,6 +1658,9 @@ if [ -z "$FILE_PATH" ]; then echo '{}'; exit 0; fi
|
|
|
1621
1658
|
BASENAME=$(basename "$FILE_PATH" 2>/dev/null || echo "$FILE_PATH")
|
|
1622
1659
|
synkro_log "editGuard checking: $BASENAME"
|
|
1623
1660
|
|
|
1661
|
+
synkro_load_config
|
|
1662
|
+
if [ "$SYNKRO_SILENT" = "true" ]; then echo '{}'; exit 0; fi
|
|
1663
|
+
|
|
1624
1664
|
BODY=$(jq -n \\
|
|
1625
1665
|
--arg file_path "$FILE_PATH" \\
|
|
1626
1666
|
--arg content "$CONTENT" \\
|
|
@@ -1728,12 +1768,8 @@ if [ -n "$CMD" ]; then
|
|
|
1728
1768
|
fi
|
|
1729
1769
|
|
|
1730
1770
|
if [ -n "$CMD_HASH" ] && [ -n "$SESSION_ID" ]; then
|
|
1731
|
-
if
|
|
1732
|
-
|
|
1733
|
-
else
|
|
1734
|
-
if ! synkro_consent_has_active "$SESSION_ID" "$CMD_HASH"; then
|
|
1735
|
-
synkro_consent_grant "$SESSION_ID" "$CMD_HASH"
|
|
1736
|
-
fi
|
|
1771
|
+
if ! synkro_consent_has_active "$SESSION_ID" "$CMD_HASH"; then
|
|
1772
|
+
synkro_consent_grant "$SESSION_ID" "$CMD_HASH"
|
|
1737
1773
|
fi
|
|
1738
1774
|
fi
|
|
1739
1775
|
|
|
@@ -3946,7 +3982,7 @@ function writeConfigEnv(opts) {
|
|
|
3946
3982
|
`SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
|
|
3947
3983
|
`SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
|
|
3948
3984
|
`SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
|
|
3949
|
-
`SYNKRO_VERSION=${shellQuoteSingle("1.4.
|
|
3985
|
+
`SYNKRO_VERSION=${shellQuoteSingle("1.4.38")}`
|
|
3950
3986
|
];
|
|
3951
3987
|
if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle(safeSynkroBin)}`);
|
|
3952
3988
|
if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
|