@synkro-sh/cli 1.4.54 → 1.4.56

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
@@ -1617,6 +1617,8 @@ async function main() {
1617
1617
  const filePath = toolInput.file_path || toolInput.notebook_path || toolInput.path || '';
1618
1618
  if (!filePath) { outputEmpty(); return; }
1619
1619
 
1620
+ if (filePath.includes('/.synkro/hooks/')) { outputEmpty(); return; }
1621
+
1620
1622
  const fileShort = basename(filePath);
1621
1623
  log('editGuard checking: ' + fileShort);
1622
1624
 
@@ -1699,7 +1701,7 @@ async function main() {
1699
1701
  });
1700
1702
  outputJson({
1701
1703
  systemMessage: tagStr + ' editGuard ' + fileShort + ' \\u2192 blocked: ' + guardReason,
1702
- hookSpecificOutput: { hookEventName: 'PreToolUse', additionalContext: denyReason },
1704
+ hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'deny', permissionDecisionReason: denyReason, additionalContext: denyReason },
1703
1705
  });
1704
1706
  return;
1705
1707
  }
@@ -1821,6 +1823,8 @@ async function main() {
1821
1823
  const filePath = toolInput.file_path || toolInput.notebook_path || toolInput.path || '';
1822
1824
  if (!filePath) { outputEmpty(); return; }
1823
1825
 
1826
+ if (filePath.includes('/.synkro/hooks/')) { outputEmpty(); return; }
1827
+
1824
1828
  const fileShort = basename(filePath);
1825
1829
  const fileExt = extname(filePath); // e.g. ".ts"
1826
1830
 
@@ -1896,7 +1900,7 @@ async function main() {
1896
1900
 
1897
1901
  outputJson({
1898
1902
  systemMessage: cweMsg,
1899
- hookSpecificOutput: { hookEventName: 'PreToolUse', additionalContext: ctx },
1903
+ hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'deny', permissionDecisionReason: ctx, additionalContext: ctx },
1900
1904
  });
1901
1905
  return;
1902
1906
  }
@@ -1955,6 +1959,8 @@ async function main() {
1955
1959
  const filePath = toolInput.file_path || toolInput.notebook_path || toolInput.path || '';
1956
1960
  if (!filePath) { outputEmpty(); return; }
1957
1961
 
1962
+ if (filePath.includes('/.synkro/hooks/')) { outputEmpty(); return; }
1963
+
1958
1964
  const fileShort = basename(filePath);
1959
1965
 
1960
1966
  let jwt = loadJwt();
@@ -2024,7 +2030,7 @@ async function main() {
2024
2030
 
2025
2031
  outputJson({
2026
2032
  systemMessage: cveMsg,
2027
- hookSpecificOutput: { hookEventName: 'PreToolUse', additionalContext: ctx },
2033
+ hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'deny', permissionDecisionReason: ctx, additionalContext: ctx },
2028
2034
  });
2029
2035
  return;
2030
2036
  }
@@ -2083,6 +2089,60 @@ async function main() {
2083
2089
  if (!jwt) { outputEmpty(); return; }
2084
2090
  jwt = await ensureFreshJwt(jwt);
2085
2091
 
2092
+ // \u2500\u2500\u2500 CVE scan for package install commands \u2500\u2500\u2500
2093
+ if (toolName === 'Bash') {
2094
+ const pkgInstallMatch = command.match(
2095
+ /(?:npm\\s+(?:install|i|add)|pnpm\\s+(?:add|install|i)|yarn\\s+add|bun\\s+(?:add|install|i)|pip\\s+install|pip3\\s+install|go\\s+get|cargo\\s+add|gem\\s+install|composer\\s+require)\\s+(.+)/
2096
+ );
2097
+ if (pkgInstallMatch) {
2098
+ const rawArgs = pkgInstallMatch[1];
2099
+ const deps: Record<string, string> = {};
2100
+ const tokens = rawArgs.split(/\\s+/);
2101
+ for (const token of tokens) {
2102
+ if (token.startsWith('-')) continue;
2103
+ const atIdx = token.lastIndexOf('@');
2104
+ if (atIdx > 0) {
2105
+ deps[token.slice(0, atIdx)] = token.slice(atIdx + 1);
2106
+ } else {
2107
+ deps[token] = '*';
2108
+ }
2109
+ }
2110
+ if (Object.keys(deps).length > 0) {
2111
+ try {
2112
+ const cveBody = { file_path: 'package.json', content: JSON.stringify({ dependencies: deps }), dependencies: deps };
2113
+ const cveResp = await fetch(GATEWAY_URL + '/api/v1/cve-scan', {
2114
+ method: 'POST',
2115
+ headers: { 'Content-Type': 'application/json', Authorization: 'Bearer ' + jwt },
2116
+ body: JSON.stringify(cveBody),
2117
+ signal: AbortSignal.timeout(8000),
2118
+ }).then(r => r.json()) as any;
2119
+
2120
+ const findings = Array.isArray(cveResp?.findings) ? cveResp.findings : [];
2121
+ if (findings.length > 0) {
2122
+ const top3 = findings.slice(0, 3).map((f: any) => {
2123
+ const id = f.cve || f.id || '?';
2124
+ const pkg = f.package || '?';
2125
+ const ver = f.version || '?';
2126
+ const title = f.title || f.summary || 'vulnerable';
2127
+ return '[' + id + '] ' + pkg + '@' + ver + ': ' + title;
2128
+ }).join('; ');
2129
+ const count = findings.length;
2130
+ const label = count === 1 ? 'advisory' : 'advisories';
2131
+ const cveMsg = '[synkro:cveScan] ' + cmdShort + ' \\u2192 ' + count + ' ' + label;
2132
+ const ctx = 'CVE: ' + top3 + '\\nDo NOT install packages with known vulnerabilities. Use a patched version or a different package.';
2133
+ outputJson({
2134
+ systemMessage: cveMsg,
2135
+ hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'deny', permissionDecisionReason: ctx, additionalContext: ctx },
2136
+ });
2137
+ return;
2138
+ }
2139
+ } catch (e) {
2140
+ log('bashGuard CVE check failed: ' + String(e));
2141
+ }
2142
+ }
2143
+ }
2144
+ }
2145
+
2086
2146
  const transcript = extractTranscript(transcriptPath);
2087
2147
  const lastPrompt = readLastPrompt();
2088
2148
 
@@ -5045,7 +5105,7 @@ function writeConfigEnv(opts) {
5045
5105
  `SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
5046
5106
  `SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
5047
5107
  `SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
5048
- `SYNKRO_VERSION=${shellQuoteSingle("1.4.54")}`
5108
+ `SYNKRO_VERSION=${shellQuoteSingle("1.4.56")}`
5049
5109
  ];
5050
5110
  if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle(safeSynkroBin)}`);
5051
5111
  if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);