@synkro-sh/cli 1.4.37 → 1.4.39
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 -57
- package/dist/bootstrap.js.map +1 -1
- package/package.json +1 -1
package/dist/bootstrap.js
CHANGED
|
@@ -508,16 +508,25 @@ synkro_channel_up() {
|
|
|
508
508
|
(exec 3<>/dev/tcp/127.0.0.1/\${SYNKRO_CHANNEL_PORT:-8929}) 2>/dev/null && exec 3<&- 3>&-
|
|
509
509
|
}
|
|
510
510
|
|
|
511
|
-
# 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.
|
|
512
512
|
synkro_load_config() {
|
|
513
513
|
local resp
|
|
514
514
|
resp=$(curl -sS "\${GATEWAY_URL}/api/v1/hook/config\${1:+?$1}" -H "Authorization: Bearer $JWT" --max-time 4 2>/dev/null || echo "")
|
|
515
515
|
if [ -z "$resp" ]; then return; fi
|
|
516
516
|
SYNKRO_CAPTURE_DEPTH=$(echo "$resp" | jq -r '.capture_depth // "local_only"' 2>/dev/null)
|
|
517
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)
|
|
518
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 "[]")
|
|
519
521
|
}
|
|
520
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
|
+
|
|
521
530
|
# Decide routing: "local" (grade on device) or "cloud" (POST to server)
|
|
522
531
|
synkro_route() {
|
|
523
532
|
[ "$SYNKRO_CAPTURE_DEPTH" = "local_only" ] && echo "local" && return
|
|
@@ -645,6 +654,8 @@ synkro_rule_mode() {
|
|
|
645
654
|
|
|
646
655
|
SYNKRO_CONSENT_FILE="$HOME/.synkro/.local-consent"
|
|
647
656
|
|
|
657
|
+
_TAB=$(printf '\\t')
|
|
658
|
+
|
|
648
659
|
synkro_consent_grant() {
|
|
649
660
|
local sid="$1" hash="$2"
|
|
650
661
|
printf '%s\\t%s\\tactive\\n' "$sid" "$hash" >> "$SYNKRO_CONSENT_FILE" 2>/dev/null || true
|
|
@@ -652,26 +663,28 @@ synkro_consent_grant() {
|
|
|
652
663
|
|
|
653
664
|
synkro_consent_has_active() {
|
|
654
665
|
local sid="$1" hash="$2"
|
|
655
|
-
grep -q "
|
|
666
|
+
grep -q "^\${sid}\${_TAB}\${hash}\${_TAB}active$" "$SYNKRO_CONSENT_FILE" 2>/dev/null
|
|
656
667
|
}
|
|
657
668
|
|
|
658
669
|
synkro_consent_consume() {
|
|
659
670
|
local sid="$1" hash="$2"
|
|
660
671
|
[ ! -f "$SYNKRO_CONSENT_FILE" ] && return
|
|
661
672
|
local tmp="\${SYNKRO_CONSENT_FILE}.tmp"
|
|
662
|
-
|
|
673
|
+
local pat="\${sid}\${_TAB}\${hash}\${_TAB}active"
|
|
674
|
+
local rep="\${sid}\${_TAB}\${hash}\${_TAB}consumed"
|
|
675
|
+
awk -v p="$pat" -v r="$rep" '{if($0==p)print r;else print}' "$SYNKRO_CONSENT_FILE" > "$tmp" 2>/dev/null && mv "$tmp" "$SYNKRO_CONSENT_FILE" 2>/dev/null || true
|
|
663
676
|
}
|
|
664
677
|
|
|
665
678
|
synkro_consent_has_consumed() {
|
|
666
679
|
local sid="$1" hash="$2"
|
|
667
|
-
grep -q "
|
|
680
|
+
grep -q "^\${sid}\${_TAB}\${hash}\${_TAB}consumed$" "$SYNKRO_CONSENT_FILE" 2>/dev/null
|
|
668
681
|
}
|
|
669
682
|
|
|
670
683
|
synkro_consent_clear_consumed() {
|
|
671
684
|
local sid="$1" hash="$2"
|
|
672
685
|
[ ! -f "$SYNKRO_CONSENT_FILE" ] && return
|
|
673
686
|
local tmp="\${SYNKRO_CONSENT_FILE}.tmp"
|
|
674
|
-
grep -v "
|
|
687
|
+
grep -v "^\${sid}\${_TAB}\${hash}\${_TAB}consumed$" "$SYNKRO_CONSENT_FILE" > "$tmp" 2>/dev/null && mv "$tmp" "$SYNKRO_CONSENT_FILE" 2>/dev/null || true
|
|
675
688
|
}
|
|
676
689
|
|
|
677
690
|
synkro_post_with_retry() {
|
|
@@ -737,17 +750,24 @@ IS_HEADLESS="\${SYNKRO_HEADLESS:-0}"
|
|
|
737
750
|
case "$PERMISSION_MODE" in acceptEdits|bypassPermissions|plan|auto) IS_HEADLESS="1" ;; esac
|
|
738
751
|
|
|
739
752
|
synkro_load_config
|
|
753
|
+
TAG=$(synkro_tag)
|
|
754
|
+
|
|
755
|
+
if [ "$SYNKRO_SILENT" = "true" ]; then
|
|
756
|
+
jq -n --arg m "$TAG bashGuard \u2192 skipped (silent mode)" '{systemMessage: $m}'
|
|
757
|
+
exit 0
|
|
758
|
+
fi
|
|
759
|
+
|
|
740
760
|
ROUTE=$(synkro_route)
|
|
741
761
|
|
|
742
762
|
if [ "$ROUTE" = "local" ]; then
|
|
743
763
|
# \u2500\u2500\u2500 Local grading (local_only privacy or local-cc channel) \u2500\u2500\u2500
|
|
744
764
|
GRADER_FILE=$(mktemp -t synkro-bash.XXXXXX)
|
|
745
765
|
trap "rm -f \\"$GRADER_FILE\\"" EXIT
|
|
746
|
-
printf '
|
|
766
|
+
printf 'Working directory: %s\\nRepo: %s\\nCommand: %s\\nUser intent: %s\\nOrg rules: %s\\n' "\${CWD:-.}" "\${GIT_REPO:-unknown}" "$COMMAND" "\${USER_INTENT:-none stated}" "\${SYNKRO_RULES:-[]}" > "$GRADER_FILE"
|
|
747
767
|
|
|
748
768
|
CC_RESP=$(synkro_local_grade bash < "$GRADER_FILE" 2>&1)
|
|
749
769
|
if [ $? -ne 0 ]; then
|
|
750
|
-
jq -n --arg m "
|
|
770
|
+
jq -n --arg m "$TAG bashGuard \u2192 pass: local grader unavailable (run synkro local-cc start)" '{systemMessage: $m}'
|
|
751
771
|
exit 0
|
|
752
772
|
fi
|
|
753
773
|
synkro_parse_local_verdict "$CC_RESP"
|
|
@@ -759,31 +779,20 @@ if [ "$ROUTE" = "local" ]; then
|
|
|
759
779
|
if [ "$LOCAL_OK" = "false" ]; then
|
|
760
780
|
RULE_MODE="\${LOCAL_RULE_MODE:-$(synkro_rule_mode "\${LOCAL_RULE_ID}")}"
|
|
761
781
|
if [ "$RULE_MODE" = "audit" ]; then
|
|
762
|
-
REASON="
|
|
782
|
+
REASON="$TAG bashGuard \u2192 warning\${LOCAL_RULE_ID:+ ($LOCAL_RULE_ID)}: \${LOCAL_REASON:-policy violation}"
|
|
763
783
|
jq -n --arg m "$REASON" '{systemMessage: $m}'
|
|
764
784
|
synkro_dispatch_capture "bash" "warning" "\${LOCAL_SEV}" "\${LOCAL_CAT}" "$TOOL_NAME" "$GIT_REPO" "$SESSION_ID" \\
|
|
765
785
|
"$COMMAND" "$LOCAL_REASON" "\${SYNKRO_RULES:-[]}" "$VIOLATED_JSON" "\${RECENT_USER_MESSAGES:-[]}"
|
|
766
786
|
else
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
else
|
|
774
|
-
if [ -n "$SESSION_ID" ] && synkro_consent_has_consumed "$SESSION_ID" "$CMD_HASH"; then
|
|
775
|
-
synkro_consent_clear_consumed "$SESSION_ID" "$CMD_HASH"
|
|
776
|
-
fi
|
|
777
|
-
if [ "$IS_HEADLESS" = "1" ]; then DEC="deny"; else DEC="ask"; fi
|
|
778
|
-
REASON="[synkro:local] bashGuard \u2192 block\${LOCAL_RULE_ID:+ ($LOCAL_RULE_ID)}: \${LOCAL_REASON:-policy violation}"
|
|
779
|
-
jq -n --arg dec "$DEC" --arg reason "$REASON" --arg ctx "$REASON" \\
|
|
780
|
-
'{systemMessage:$reason,hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:$dec,permissionDecisionReason:$reason,additionalContext:$ctx}}'
|
|
781
|
-
synkro_dispatch_capture "bash" "block" "\${LOCAL_SEV}" "\${LOCAL_CAT}" "$TOOL_NAME" "$GIT_REPO" "$SESSION_ID" \\
|
|
782
|
-
"$COMMAND" "$LOCAL_REASON" "\${SYNKRO_RULES:-[]}" "$VIOLATED_JSON" "\${RECENT_USER_MESSAGES:-[]}"
|
|
783
|
-
fi
|
|
787
|
+
if [ "$IS_HEADLESS" = "1" ]; then DEC="deny"; else DEC="ask"; fi
|
|
788
|
+
REASON="$TAG bashGuard \u2192 block\${LOCAL_RULE_ID:+ ($LOCAL_RULE_ID)}: \${LOCAL_REASON:-policy violation}"
|
|
789
|
+
jq -n --arg dec "$DEC" --arg reason "$REASON" --arg ctx "$REASON" \\
|
|
790
|
+
'{systemMessage:$reason,hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:$dec,permissionDecisionReason:$reason,additionalContext:$ctx}}'
|
|
791
|
+
synkro_dispatch_capture "bash" "block" "\${LOCAL_SEV}" "\${LOCAL_CAT}" "$TOOL_NAME" "$GIT_REPO" "$SESSION_ID" \\
|
|
792
|
+
"$COMMAND" "$LOCAL_REASON" "\${SYNKRO_RULES:-[]}" "$VIOLATED_JSON" "\${RECENT_USER_MESSAGES:-[]}"
|
|
784
793
|
fi
|
|
785
794
|
else
|
|
786
|
-
jq -n --arg m "
|
|
795
|
+
jq -n --arg m "$TAG bashGuard \u2192 pass: \${LOCAL_REASON:-no policy violations detected}" '{systemMessage: $m}'
|
|
787
796
|
synkro_dispatch_capture "bash" "pass" "audit" "\${LOCAL_CAT:-trivial_utility}" "$TOOL_NAME" "$GIT_REPO" "$SESSION_ID" \\
|
|
788
797
|
"$COMMAND" "$LOCAL_REASON" "\${SYNKRO_RULES:-[]}" "[]" "\${RECENT_USER_MESSAGES:-[]}"
|
|
789
798
|
fi
|
|
@@ -938,17 +947,24 @@ if [ -n "$TRANSCRIPT_PATH" ] && [ -f "$TRANSCRIPT_PATH" ]; then
|
|
|
938
947
|
fi
|
|
939
948
|
|
|
940
949
|
synkro_load_config
|
|
950
|
+
TAG=$(synkro_tag)
|
|
951
|
+
|
|
952
|
+
if [ "$SYNKRO_SILENT" = "true" ]; then
|
|
953
|
+
jq -n --arg m "$TAG editGuard \u2192 skipped (silent mode)" '{systemMessage: $m}'
|
|
954
|
+
exit 0
|
|
955
|
+
fi
|
|
956
|
+
|
|
941
957
|
ROUTE=$(synkro_route)
|
|
942
958
|
|
|
943
959
|
if [ "$ROUTE" = "local" ]; then
|
|
944
960
|
# \u2500\u2500\u2500 Local grading (local_only privacy or local-cc channel) \u2500\u2500\u2500
|
|
945
961
|
GRADER_FILE=$(mktemp -t synkro-edit.XXXXXX)
|
|
946
962
|
trap "rm -f \\"$GRADER_FILE\\"" EXIT
|
|
947
|
-
printf '
|
|
963
|
+
printf 'Working directory: %s\\nRepo: %s\\nFile: %s\\nProposed content (first 4000 chars):\\n%s\\nUser intent: %s\\nOrg rules: %s\\n' "\${CWD:-.}" "\${GIT_REPO:-unknown}" "$FILE_PATH" "$(printf '%s' "$PROPOSED" | head -c 4000)" "\${USER_INTENT:-none stated}" "\${SYNKRO_RULES:-[]}" > "$GRADER_FILE"
|
|
948
964
|
|
|
949
965
|
CC_RESP=$(synkro_local_grade edit < "$GRADER_FILE" 2>&1)
|
|
950
966
|
if [ $? -ne 0 ]; then
|
|
951
|
-
jq -n --arg m "
|
|
967
|
+
jq -n --arg m "$TAG editGuard \u2192 pass: local grader unavailable (run synkro local-cc start)" '{systemMessage: $m}'
|
|
952
968
|
exit 0
|
|
953
969
|
fi
|
|
954
970
|
synkro_parse_local_verdict "$CC_RESP"
|
|
@@ -961,20 +977,20 @@ if [ "$ROUTE" = "local" ]; then
|
|
|
961
977
|
if [ "$LOCAL_OK" = "false" ]; then
|
|
962
978
|
RULE_MODE="\${LOCAL_RULE_MODE:-$(synkro_rule_mode "\${LOCAL_RULE_ID}")}"
|
|
963
979
|
if [ "$RULE_MODE" = "audit" ]; then
|
|
964
|
-
REASON="
|
|
980
|
+
REASON="$TAG editGuard $FILE_SHORT \u2192 warning\${LOCAL_RULE_ID:+ ($LOCAL_RULE_ID)}: \${LOCAL_REASON:-policy violation}"
|
|
965
981
|
jq -n --arg m "$REASON" '{systemMessage: $m}'
|
|
966
982
|
synkro_dispatch_capture "edit" "warning" "\${LOCAL_SEV}" "\${LOCAL_CAT}" "$TOOL_NAME" "$GIT_REPO" "$SESSION_ID" \\
|
|
967
983
|
"$EDIT_CONTENT" "$LOCAL_REASON" "\${SYNKRO_RULES:-[]}" "$VIOLATED_JSON" "[]"
|
|
968
984
|
else
|
|
969
985
|
if [ "$IS_HEADLESS" = "1" ]; then DEC="deny"; else DEC="ask"; fi
|
|
970
|
-
REASON="
|
|
986
|
+
REASON="$TAG editGuard $FILE_SHORT \u2192 block\${LOCAL_RULE_ID:+ ($LOCAL_RULE_ID)}: \${LOCAL_REASON:-policy violation}"
|
|
971
987
|
jq -n --arg dec "$DEC" --arg reason "$REASON" --arg ctx "$REASON" \\
|
|
972
988
|
'{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:$dec,permissionDecisionReason:$reason,additionalContext:$ctx}}'
|
|
973
989
|
synkro_dispatch_capture "edit" "block" "\${LOCAL_SEV}" "\${LOCAL_CAT}" "$TOOL_NAME" "$GIT_REPO" "$SESSION_ID" \\
|
|
974
990
|
"$EDIT_CONTENT" "$LOCAL_REASON" "\${SYNKRO_RULES:-[]}" "$VIOLATED_JSON" "[]"
|
|
975
991
|
fi
|
|
976
992
|
else
|
|
977
|
-
jq -n --arg m "
|
|
993
|
+
jq -n --arg m "$TAG editGuard $FILE_SHORT \u2192 pass: \${LOCAL_REASON:-no policy violations detected}" '{systemMessage: $m}'
|
|
978
994
|
synkro_dispatch_capture "edit" "pass" "audit" "\${LOCAL_CAT:-trivial_edit}" "$TOOL_NAME" "$GIT_REPO" "$SESSION_ID" \\
|
|
979
995
|
"$EDIT_CONTENT" "$LOCAL_REASON" "\${SYNKRO_RULES:-[]}" "[]" "[]"
|
|
980
996
|
fi
|
|
@@ -1099,13 +1115,19 @@ while [ "$_PKG_DIR" != "/" ]; do
|
|
|
1099
1115
|
done
|
|
1100
1116
|
|
|
1101
1117
|
synkro_load_config
|
|
1118
|
+
TAG=$(synkro_tag)
|
|
1119
|
+
|
|
1120
|
+
if [ "$SYNKRO_SILENT" = "true" ]; then
|
|
1121
|
+
echo '{}'; exit 0
|
|
1122
|
+
fi
|
|
1123
|
+
|
|
1102
1124
|
ROUTE=$(synkro_route)
|
|
1103
1125
|
|
|
1104
1126
|
if [ "$ROUTE" = "local" ]; then
|
|
1105
1127
|
# \u2500\u2500\u2500 Local edit scan (local_only privacy or local-cc channel) \u2500\u2500\u2500
|
|
1106
1128
|
GRADER_FILE=$(mktemp -t synkro-escan.XXXXXX)
|
|
1107
1129
|
trap "rm -f \\"$GRADER_FILE\\"" EXIT
|
|
1108
|
-
printf '
|
|
1130
|
+
printf 'Working directory: %s\\nRepo: %s\\nFile: %s\\nContent (first 4000 chars):\\n%s\\nOrg rules: %s\\n' "\${CWD:-.}" "\${GIT_REPO:-unknown}" "$FILE_PATH" "$(printf '%s' "$FILE_CONTENT" | head -c 4000)" "\${SYNKRO_RULES:-[]}" > "$GRADER_FILE"
|
|
1109
1131
|
|
|
1110
1132
|
CC_RESP=$(synkro_local_grade edit < "$GRADER_FILE" 2>&1)
|
|
1111
1133
|
if [ $? -ne 0 ]; then
|
|
@@ -1120,18 +1142,18 @@ if [ "$ROUTE" = "local" ]; then
|
|
|
1120
1142
|
if [ "$LOCAL_OK" = "false" ]; then
|
|
1121
1143
|
RULE_MODE="\${LOCAL_RULE_MODE:-$(synkro_rule_mode "\${LOCAL_RULE_ID}")}"
|
|
1122
1144
|
if [ "$RULE_MODE" = "audit" ]; then
|
|
1123
|
-
REASON="
|
|
1145
|
+
REASON="$TAG editScan $BASENAME \u2192 warning\${LOCAL_RULE_ID:+ ($LOCAL_RULE_ID)}: \${LOCAL_REASON:-policy violation}"
|
|
1124
1146
|
jq -n --arg m "$REASON" '{systemMessage: $m}'
|
|
1125
1147
|
synkro_dispatch_capture "edit_scan" "warning" "\${LOCAL_SEV}" "\${LOCAL_CAT}" "$TOOL_NAME" "$GIT_REPO" "$SESSION_ID" \\
|
|
1126
1148
|
"$SCAN_CONTENT" "$LOCAL_REASON" "\${SYNKRO_RULES:-[]}" "$SCAN_VIOLATED" "[]"
|
|
1127
1149
|
else
|
|
1128
|
-
REASON="
|
|
1150
|
+
REASON="$TAG editScan $BASENAME \u2192 block: \${LOCAL_REASON:-policy violation}"
|
|
1129
1151
|
jq -n --arg m "$REASON" '{systemMessage: $m, additionalContext: $m}'
|
|
1130
1152
|
synkro_dispatch_capture "edit_scan" "block" "\${LOCAL_SEV}" "\${LOCAL_CAT}" "$TOOL_NAME" "$GIT_REPO" "$SESSION_ID" \\
|
|
1131
1153
|
"$SCAN_CONTENT" "$LOCAL_REASON" "\${SYNKRO_RULES:-[]}" "$SCAN_VIOLATED" "[]"
|
|
1132
1154
|
fi
|
|
1133
1155
|
else
|
|
1134
|
-
jq -n --arg m "
|
|
1156
|
+
jq -n --arg m "$TAG editScan $BASENAME \u2192 pass: \${LOCAL_REASON:-no policy violations detected}" '{systemMessage: $m}'
|
|
1135
1157
|
synkro_dispatch_capture "edit_scan" "pass" "audit" "\${LOCAL_CAT:-trivial_edit}" "$TOOL_NAME" "$GIT_REPO" "$SESSION_ID" \\
|
|
1136
1158
|
"$SCAN_CONTENT" "$LOCAL_REASON" "\${SYNKRO_RULES:-[]}" "[]" "[]"
|
|
1137
1159
|
fi
|
|
@@ -1205,12 +1227,19 @@ PLAN_SHORT=$(printf '%s' "$PLAN" | head -c 80)
|
|
|
1205
1227
|
synkro_log "planReview checking: $PLAN_SHORT..."
|
|
1206
1228
|
|
|
1207
1229
|
synkro_load_config
|
|
1230
|
+
TAG=$(synkro_tag)
|
|
1231
|
+
|
|
1232
|
+
if [ "$SYNKRO_SILENT" = "true" ]; then
|
|
1233
|
+
jq -n --arg m "$TAG planReview \u2192 skipped (silent mode)" '{systemMessage: $m}'
|
|
1234
|
+
exit 0
|
|
1235
|
+
fi
|
|
1236
|
+
|
|
1208
1237
|
ROUTE=$(synkro_route)
|
|
1209
1238
|
|
|
1210
1239
|
if [ "$ROUTE" = "local" ]; then
|
|
1211
1240
|
GRADER_FILE=$(mktemp -t synkro-plan.XXXXXX)
|
|
1212
1241
|
trap "rm -f \\"$GRADER_FILE\\"" EXIT
|
|
1213
|
-
printf '
|
|
1242
|
+
printf 'Working directory: %s\\nRepo: %s\\nPlan:\\n%s\\nOrg rules: %s\\n' "\${CWD:-.}" "\${GIT_REPO:-unknown}" "$(printf '%s' "$PLAN" | head -c 8000)" "\${SYNKRO_RULES:-[]}" > "$GRADER_FILE"
|
|
1214
1243
|
|
|
1215
1244
|
CC_RESP=$(synkro_local_grade plan < "$GRADER_FILE" 2>&1)
|
|
1216
1245
|
if [ $? -ne 0 ]; then
|
|
@@ -1225,12 +1254,12 @@ if [ "$ROUTE" = "local" ]; then
|
|
|
1225
1254
|
if [ "$LOCAL_OK" = "false" ]; then
|
|
1226
1255
|
VCOUNT=$(printf '%s' "$CC_RESP" | grep -c '<violation>' 2>/dev/null || echo "0")
|
|
1227
1256
|
[ "$VCOUNT" = "0" ] && VCOUNT="1"
|
|
1228
|
-
MSG="
|
|
1257
|
+
MSG="$TAG planReview \u2192 \${VCOUNT} rule(s) relevant\${LOCAL_RULE_ID:+ (first: $LOCAL_RULE_ID)}: \${LOCAL_REASON:-check org rules during implementation}"
|
|
1229
1258
|
jq -n --arg m "$MSG" '{systemMessage: $m}'
|
|
1230
1259
|
synkro_dispatch_capture "plan_review" "advisory" "\${LOCAL_SEV}" "\${LOCAL_CAT}" "ExitPlanMode" "$GIT_REPO" "$SESSION_ID" \\
|
|
1231
1260
|
"$PLAN_CONTENT" "$LOCAL_REASON" "\${SYNKRO_RULES:-[]}" "$PLAN_VIOLATED" "[]"
|
|
1232
1261
|
else
|
|
1233
|
-
jq -n --arg m "
|
|
1262
|
+
jq -n --arg m "$TAG planReview \u2192 clean: \${LOCAL_REASON:-no relevant org rules for this plan}" '{systemMessage: $m}'
|
|
1234
1263
|
synkro_dispatch_capture "plan_review" "clean" "audit" "\${LOCAL_CAT:-general}" "ExitPlanMode" "$GIT_REPO" "$SESSION_ID" \\
|
|
1235
1264
|
"$PLAN_CONTENT" "$LOCAL_REASON" "\${SYNKRO_RULES:-[]}" "[]" "[]"
|
|
1236
1265
|
fi
|
|
@@ -1271,7 +1300,7 @@ fi
|
|
|
1271
1300
|
HR=$(echo "$RESP" | jq -c '.hook_response')
|
|
1272
1301
|
if echo "$HR" | jq -e '.hookSpecificOutput.permissionDecision' >/dev/null 2>&1; then
|
|
1273
1302
|
REASON=$(echo "$HR" | jq -r '.hookSpecificOutput.permissionDecisionReason // "check org rules"' 2>/dev/null)
|
|
1274
|
-
jq -n --arg m "
|
|
1303
|
+
jq -n --arg m "$TAG planReview \u2192 advisory: $REASON" '{systemMessage: $m}'
|
|
1275
1304
|
else
|
|
1276
1305
|
echo "$HR"
|
|
1277
1306
|
fi
|
|
@@ -1339,10 +1368,12 @@ OPEN=$(echo "$RESP" | jq -r '.open // 0' 2>/dev/null)
|
|
|
1339
1368
|
|
|
1340
1369
|
if [ "\${EDITS:-0}" = "0" ] || [ -z "$EDITS" ]; then echo '{}'; exit 0; fi
|
|
1341
1370
|
|
|
1371
|
+
synkro_load_config
|
|
1372
|
+
TAG=$(synkro_tag)
|
|
1342
1373
|
if [ "\${FINDINGS:-0}" = "0" ] || [ -z "$FINDINGS" ]; then
|
|
1343
|
-
SYS_MSG="
|
|
1374
|
+
SYS_MSG="$TAG stop \u2192 0 issues across \${EDITS} edit(s), session complete"
|
|
1344
1375
|
else
|
|
1345
|
-
SYS_MSG="
|
|
1376
|
+
SYS_MSG="$TAG stop \u2192 \${FINDINGS} finding(s): \${AUTO_FIXED} auto-fixed, \${OPEN} open"
|
|
1346
1377
|
fi
|
|
1347
1378
|
|
|
1348
1379
|
jq -n --arg m "$SYS_MSG" '{systemMessage: $m}'
|
|
@@ -1356,11 +1387,30 @@ JWT=$(synkro_load_jwt)
|
|
|
1356
1387
|
|
|
1357
1388
|
# Route preamble
|
|
1358
1389
|
SYNKRO_PORT="\${SYNKRO_CHANNEL_PORT:-8929}"
|
|
1390
|
+
PAYLOAD=$(cat)
|
|
1391
|
+
CWD=$(echo "$PAYLOAD" | jq -r '.cwd // empty' 2>/dev/null)
|
|
1392
|
+
SESSION_ID=$(echo "$PAYLOAD" | jq -r '.session_id // empty' 2>/dev/null)
|
|
1393
|
+
GIT_REPO=$(synkro_detect_repo "\${CWD:-.}")
|
|
1394
|
+
|
|
1395
|
+
RESP=""
|
|
1396
|
+
if [ -n "$JWT" ]; then
|
|
1397
|
+
RESP=$(curl -sS -G "\${GATEWAY_URL}/api/v1/hook/config" \\
|
|
1398
|
+
--data-urlencode "session_id=\${SESSION_ID:-}" \\
|
|
1399
|
+
--data-urlencode "repo=\${GIT_REPO:-}" \\
|
|
1400
|
+
-H "Authorization: Bearer $JWT" --max-time 3 2>/dev/null || echo "")
|
|
1401
|
+
if [ -n "$RESP" ]; then
|
|
1402
|
+
SYNKRO_SILENT=$(echo "$RESP" | jq -r '.silent_mode // false' 2>/dev/null)
|
|
1403
|
+
SYNKRO_POLICY_NAME=$(echo "$RESP" | jq -r '.active_policy_name // empty' 2>/dev/null)
|
|
1404
|
+
fi
|
|
1405
|
+
fi
|
|
1406
|
+
|
|
1407
|
+
TAG=$(synkro_tag)
|
|
1408
|
+
|
|
1359
1409
|
if (exec 3<>/dev/tcp/127.0.0.1/"$SYNKRO_PORT") 2>/dev/null; then
|
|
1360
1410
|
exec 3<&- 3>&- 2>/dev/null || true
|
|
1361
|
-
ROUTE_LINE="
|
|
1411
|
+
ROUTE_LINE="$TAG inference: local-cc (channel reachable on 127.0.0.1:$SYNKRO_PORT)"
|
|
1362
1412
|
else
|
|
1363
|
-
ROUTE_LINE="
|
|
1413
|
+
ROUTE_LINE="$TAG inference: cloud (local-cc channel not reachable)"
|
|
1364
1414
|
fi
|
|
1365
1415
|
|
|
1366
1416
|
if [ -z "$JWT" ]; then
|
|
@@ -1368,16 +1418,6 @@ if [ -z "$JWT" ]; then
|
|
|
1368
1418
|
exit 0
|
|
1369
1419
|
fi
|
|
1370
1420
|
|
|
1371
|
-
PAYLOAD=$(cat)
|
|
1372
|
-
CWD=$(echo "$PAYLOAD" | jq -r '.cwd // empty' 2>/dev/null)
|
|
1373
|
-
SESSION_ID=$(echo "$PAYLOAD" | jq -r '.session_id // empty' 2>/dev/null)
|
|
1374
|
-
GIT_REPO=$(synkro_detect_repo "\${CWD:-.}")
|
|
1375
|
-
|
|
1376
|
-
RESP=$(curl -sS -G "\${GATEWAY_URL}/api/v1/hook/config" \\
|
|
1377
|
-
--data-urlencode "session_id=\${SESSION_ID:-}" \\
|
|
1378
|
-
--data-urlencode "repo=\${GIT_REPO:-}" \\
|
|
1379
|
-
-H "Authorization: Bearer $JWT" --max-time 3 2>/dev/null || echo "")
|
|
1380
|
-
|
|
1381
1421
|
OPEN=0
|
|
1382
1422
|
if [ -n "$RESP" ]; then
|
|
1383
1423
|
OPEN=$(echo "$RESP" | jq -r '.session_context.open_findings // 0' 2>/dev/null)
|
|
@@ -1387,9 +1427,9 @@ if [ "$OPEN" = "0" ] || [ -z "$OPEN" ]; then
|
|
|
1387
1427
|
jq -n --arg m "$ROUTE_LINE" '{systemMessage: $m}'
|
|
1388
1428
|
else
|
|
1389
1429
|
if [ "$OPEN" = "1" ]; then
|
|
1390
|
-
SYS_MSG="$ROUTE_LINE"$'\\n'"
|
|
1430
|
+
SYS_MSG="$ROUTE_LINE"$'\\n'"$TAG session start \u2192 1 open finding in this repo from a prior session."
|
|
1391
1431
|
else
|
|
1392
|
-
SYS_MSG="$ROUTE_LINE"$'\\n'"
|
|
1432
|
+
SYS_MSG="$ROUTE_LINE"$'\\n'"$TAG session start \u2192 \${OPEN} open findings in this repo from prior sessions."
|
|
1393
1433
|
fi
|
|
1394
1434
|
jq -n --arg m "$SYS_MSG" '{systemMessage: $m}'
|
|
1395
1435
|
fi
|
|
@@ -1425,6 +1465,7 @@ BODY=$(jq -n --arg sid "$SESSION_ID" --arg tid "$TOOL_USE_ID" \\
|
|
|
1425
1465
|
# Local consent tracking: command ran = user consented
|
|
1426
1466
|
# On success \u2192 consume (next attempt blocks fresh)
|
|
1427
1467
|
# On failure \u2192 grant active (retry allowed)
|
|
1468
|
+
# Consent tracking: on success \u2192 consume (next run blocks fresh), on error \u2192 grant (retry allowed)
|
|
1428
1469
|
if [ -n "$CMD_HASH" ] && [ -n "$SESSION_ID" ]; then
|
|
1429
1470
|
if [ "$IS_ERROR" = "false" ]; then
|
|
1430
1471
|
synkro_consent_consume "$SESSION_ID" "$CMD_HASH"
|
|
@@ -1459,7 +1500,7 @@ if [ -z "$SESSION_ID" ] || [ -z "$TRANSCRIPT_PATH" ] || [ ! -f "$TRANSCRIPT_PATH
|
|
|
1459
1500
|
fi
|
|
1460
1501
|
|
|
1461
1502
|
# Usage telemetry \u2014 last turn only (metadata, ungated by privacy/consent)
|
|
1462
|
-
_LAST_ASST=$(
|
|
1503
|
+
_LAST_ASST=$(grep '"type":"assistant"' "$TRANSCRIPT_PATH" 2>/dev/null | tail -1)
|
|
1463
1504
|
if [ -n "$_LAST_ASST" ]; then
|
|
1464
1505
|
_CC_MODEL=$(echo "$_LAST_ASST" | jq -r '.message.model // empty' 2>/dev/null)
|
|
1465
1506
|
_TI=$(echo "$_LAST_ASST" | jq -r '.message.usage.input_tokens // 0' 2>/dev/null)
|
|
@@ -1562,6 +1603,9 @@ GIT_REPO=$(synkro_detect_repo "\${CWD:-.}")
|
|
|
1562
1603
|
CMD_SHORT=$(printf '%s' "$COMMAND" | head -c 80)
|
|
1563
1604
|
synkro_log "bashGuard checking: $CMD_SHORT"
|
|
1564
1605
|
|
|
1606
|
+
synkro_load_config
|
|
1607
|
+
if [ "$SYNKRO_SILENT" = "true" ]; then echo '{}'; exit 0; fi
|
|
1608
|
+
|
|
1565
1609
|
BODY=$(jq -n \\
|
|
1566
1610
|
--arg cmd "$COMMAND" \\
|
|
1567
1611
|
--arg session_id "$SESSION_ID" \\
|
|
@@ -1615,6 +1659,9 @@ if [ -z "$FILE_PATH" ]; then echo '{}'; exit 0; fi
|
|
|
1615
1659
|
BASENAME=$(basename "$FILE_PATH" 2>/dev/null || echo "$FILE_PATH")
|
|
1616
1660
|
synkro_log "editGuard checking: $BASENAME"
|
|
1617
1661
|
|
|
1662
|
+
synkro_load_config
|
|
1663
|
+
if [ "$SYNKRO_SILENT" = "true" ]; then echo '{}'; exit 0; fi
|
|
1664
|
+
|
|
1618
1665
|
BODY=$(jq -n \\
|
|
1619
1666
|
--arg file_path "$FILE_PATH" \\
|
|
1620
1667
|
--arg content "$CONTENT" \\
|
|
@@ -3940,7 +3987,7 @@ function writeConfigEnv(opts) {
|
|
|
3940
3987
|
`SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
|
|
3941
3988
|
`SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
|
|
3942
3989
|
`SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
|
|
3943
|
-
`SYNKRO_VERSION=${shellQuoteSingle("1.4.
|
|
3990
|
+
`SYNKRO_VERSION=${shellQuoteSingle("1.4.39")}`
|
|
3944
3991
|
];
|
|
3945
3992
|
if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle(safeSynkroBin)}`);
|
|
3946
3993
|
if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
|