@synkro-sh/cli 1.6.45 → 1.6.46
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 +120 -18
- package/dist/bootstrap.js.map +1 -1
- package/package.json +1 -1
package/dist/bootstrap.js
CHANGED
|
@@ -1280,6 +1280,39 @@ export function effectiveGraderPool(synkroFile: SynkroFileConfig, hookAgentKind:
|
|
|
1280
1280
|
return 'cursor';
|
|
1281
1281
|
}
|
|
1282
1282
|
|
|
1283
|
+
// \u2500\u2500\u2500 .synkro presence (per-repo onboarding) \u2500\u2500\u2500
|
|
1284
|
+
// A repo is "onboarded" to Synkro when it has a .synkro file at its git root.
|
|
1285
|
+
// The hooks are installed globally, so they fire in every repo \u2014 including ones
|
|
1286
|
+
// the user never set up. Without a .synkro there, grading is SKIPPED gracefully
|
|
1287
|
+
// rather than attempting a grade that surfaces a confusing "grader unavailable"
|
|
1288
|
+
// error: the tool call passes through and we show a one-time hint pointing at
|
|
1289
|
+
// "synkro install".
|
|
1290
|
+
export function synkroFilePresent(cwd?: string): boolean {
|
|
1291
|
+
try {
|
|
1292
|
+
const root = cwd ? findGitRoot(cwd) : '';
|
|
1293
|
+
if (!root) return false;
|
|
1294
|
+
return existsSync(root + '/.synkro');
|
|
1295
|
+
} catch { return false; }
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
const NO_SYNKRO_HINT_DIR = join(HOME, '.synkro', '.no-synkro-hint');
|
|
1299
|
+
|
|
1300
|
+
// Returns the onboarding hint the FIRST time a session touches a repo with no
|
|
1301
|
+
// .synkro file, then null on subsequent calls so it doesn't repeat on every
|
|
1302
|
+
// tool call. Caller passes null straight through to outputEmpty().
|
|
1303
|
+
export function noSynkroSkipMessage(sessionId: string): string | null {
|
|
1304
|
+
try {
|
|
1305
|
+
mkdirSync(NO_SYNKRO_HINT_DIR, { recursive: true });
|
|
1306
|
+
const key = (sessionId || 'nosession').replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
1307
|
+
const marker = join(NO_SYNKRO_HINT_DIR, key);
|
|
1308
|
+
if (existsSync(marker)) return null;
|
|
1309
|
+
writeFileSync(marker, '', { flag: 'w' });
|
|
1310
|
+
} catch {
|
|
1311
|
+
// best-effort dedup \u2014 if the marker can't be written, still show the hint
|
|
1312
|
+
}
|
|
1313
|
+
return '[synkro] No .synkro config in this repo \u2014 grading skipped. Run \`synkro install\` here to enable Synkro.';
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1283
1316
|
// \u2500\u2500\u2500 Channel Health \u2500\u2500\u2500
|
|
1284
1317
|
|
|
1285
1318
|
export async function channelUp(port = 18929): Promise<boolean> {
|
|
@@ -3355,7 +3388,7 @@ import {
|
|
|
3355
3388
|
outputJson, outputEmpty, setupCursorHookSignals, installHookWatchdog, isEditTool, hookSessionId, GATEWAY_URL,
|
|
3356
3389
|
logGraderUnavailable, graderUnavailableMessage, filterRules, ruleFilterText, normalizeMode, countEditLineDelta,
|
|
3357
3390
|
captureLineMetrics, cursorModelFromPayload, resolveTranscriptPath, isCursorInvokingCcHook,
|
|
3358
|
-
loadSynkroFile, effectiveGraderPool,
|
|
3391
|
+
loadSynkroFile, effectiveGraderPool, synkroFilePresent, noSynkroSkipMessage,
|
|
3359
3392
|
type HookConfig, type Rule,
|
|
3360
3393
|
} from './_synkro-common.ts';
|
|
3361
3394
|
import { existsSync, readFileSync } from 'node:fs';
|
|
@@ -3390,6 +3423,13 @@ async function main() {
|
|
|
3390
3423
|
|
|
3391
3424
|
if (filePath.includes('/.synkro/hooks/')) { outputEmpty(); return; }
|
|
3392
3425
|
|
|
3426
|
+
if (!synkroFilePresent(cwd)) {
|
|
3427
|
+
const _skipMsg = noSynkroSkipMessage(sessionId);
|
|
3428
|
+
if (_skipMsg) outputJson({ systemMessage: _skipMsg, hookSpecificOutput: { hookEventName: 'PreToolUse', additionalContext: _skipMsg } });
|
|
3429
|
+
else outputEmpty();
|
|
3430
|
+
return;
|
|
3431
|
+
}
|
|
3432
|
+
|
|
3393
3433
|
const fileShort = basename(filePath);
|
|
3394
3434
|
log('editGuard checking: ' + fileShort);
|
|
3395
3435
|
|
|
@@ -3613,7 +3653,7 @@ import {
|
|
|
3613
3653
|
outputJson, outputEmpty, setupCursorHookSignals, installHookWatchdog, isEditTool, isShellTool, isCursorHookFormat,
|
|
3614
3654
|
extractShellCodeWrites, hookSessionId, filePathFromToolInput, emitBlockScanFindings, dispatchFinding, dispatchCapture, GATEWAY_URL,
|
|
3615
3655
|
logGraderUnavailable, graderUnavailableMessage, resolveTranscriptPath, isCursorInvokingCcHook,
|
|
3616
|
-
loadSynkroFile, effectiveGraderPool,
|
|
3656
|
+
loadSynkroFile, effectiveGraderPool, synkroFilePresent, noSynkroSkipMessage,
|
|
3617
3657
|
} from './_synkro-common.ts';
|
|
3618
3658
|
import { basename, extname, resolve, join, dirname } from 'node:path';
|
|
3619
3659
|
import { readFileSync, readdirSync, existsSync } from 'node:fs';
|
|
@@ -3767,6 +3807,13 @@ async function main() {
|
|
|
3767
3807
|
|
|
3768
3808
|
if (isCursorInvokingCcHook(agentKind, ccModel)) { outputEmpty(); return; }
|
|
3769
3809
|
|
|
3810
|
+
if (!synkroFilePresent(cwd)) {
|
|
3811
|
+
const _skipMsg = noSynkroSkipMessage(sessionId);
|
|
3812
|
+
if (_skipMsg) outputJson({ systemMessage: _skipMsg, hookSpecificOutput: { hookEventName: 'PreToolUse', additionalContext: _skipMsg } });
|
|
3813
|
+
else outputEmpty();
|
|
3814
|
+
return;
|
|
3815
|
+
}
|
|
3816
|
+
|
|
3770
3817
|
const targets: CweScanTarget[] = [];
|
|
3771
3818
|
|
|
3772
3819
|
if (isCursorHookFormat() && (shellCommand || isShellTool(toolName))) {
|
|
@@ -4173,7 +4220,7 @@ import {
|
|
|
4173
4220
|
loadJwt, ensureFreshJwt, detectRepo, loadConfig, route, tag,
|
|
4174
4221
|
reconstructContent, readStdin, findNearestDeps, filePathFromToolInput, log,
|
|
4175
4222
|
outputJson, outputEmpty, setupCursorHookSignals, isEditTool, hookSessionId, dispatchFinding, dispatchCapture, dispatchScanResult, extractTranscript, emitBlockScanFindings, resolveTranscriptPath, GATEWAY_URL,
|
|
4176
|
-
isCursorHookFormat,
|
|
4223
|
+
isCursorHookFormat, synkroFilePresent, noSynkroSkipMessage,
|
|
4177
4224
|
} from './_synkro-common.ts';
|
|
4178
4225
|
import { basename } from 'node:path';
|
|
4179
4226
|
import { readFileSync } from 'node:fs';
|
|
@@ -4219,6 +4266,13 @@ async function main() {
|
|
|
4219
4266
|
|
|
4220
4267
|
if (filePath.includes('/.synkro/hooks/')) { outputEmpty(); return; }
|
|
4221
4268
|
|
|
4269
|
+
if (!synkroFilePresent(cwd)) {
|
|
4270
|
+
const _skipMsg = noSynkroSkipMessage(sessionId);
|
|
4271
|
+
if (_skipMsg) outputJson({ systemMessage: _skipMsg, hookSpecificOutput: { hookEventName: 'PreToolUse', additionalContext: _skipMsg } });
|
|
4272
|
+
else outputEmpty();
|
|
4273
|
+
return;
|
|
4274
|
+
}
|
|
4275
|
+
|
|
4222
4276
|
const fileShort = basename(filePath);
|
|
4223
4277
|
|
|
4224
4278
|
let jwt = loadJwt();
|
|
@@ -4455,7 +4509,7 @@ import {
|
|
|
4455
4509
|
loadJwt, ensureFreshJwt, detectRepo, loadConfig, route, tag,
|
|
4456
4510
|
readStdin, runInstallScan, emitBlockScanFindings, dispatchCapture, dispatchScanResult, hashCommand,
|
|
4457
4511
|
outputJson, outputEmpty, setupCursorHookSignals, isShellTool, hookSessionId, log, GATEWAY_URL,
|
|
4458
|
-
resolveTranscriptPath, isCursorHookFormat, loadSynkroFile, effectiveGraderPool,
|
|
4512
|
+
resolveTranscriptPath, isCursorHookFormat, loadSynkroFile, effectiveGraderPool, synkroFilePresent, noSynkroSkipMessage,
|
|
4459
4513
|
} from './_synkro-common.ts';
|
|
4460
4514
|
import { writeFileSync, mkdirSync } from 'node:fs';
|
|
4461
4515
|
import { join } from 'node:path';
|
|
@@ -4480,6 +4534,14 @@ async function main() {
|
|
|
4480
4534
|
// beforeShellExecution supplies command directly; preToolUse uses tool_name + tool_input.
|
|
4481
4535
|
if (!isShellTool(toolName) && typeof payload.command !== 'string') { outputEmpty(); return; }
|
|
4482
4536
|
|
|
4537
|
+
const _cwd = payload.cwd || (Array.isArray(payload.workspace_roots) ? payload.workspace_roots[0] : '') || '';
|
|
4538
|
+
if (!synkroFilePresent(_cwd)) {
|
|
4539
|
+
const _skipMsg = noSynkroSkipMessage(hookSessionId(payload));
|
|
4540
|
+
if (_skipMsg) outputJson({ systemMessage: _skipMsg, hookSpecificOutput: { hookEventName: 'PreToolUse', additionalContext: _skipMsg } });
|
|
4541
|
+
else outputEmpty();
|
|
4542
|
+
return;
|
|
4543
|
+
}
|
|
4544
|
+
|
|
4483
4545
|
let jwt = loadJwt();
|
|
4484
4546
|
if (!jwt) { outputEmpty(); return; }
|
|
4485
4547
|
jwt = await ensureFreshJwt(jwt);
|
|
@@ -4576,7 +4638,7 @@ import {
|
|
|
4576
4638
|
extractTranscript, readLastPrompt, appendSessionAction, readSessionLog, compressSessionLog, log,
|
|
4577
4639
|
outputJson, outputEmpty, setupCursorHookSignals, installHookWatchdog, isShellTool, hookSessionId, GATEWAY_URL,
|
|
4578
4640
|
logGraderUnavailable, graderUnavailableMessage, filterRules, ruleFilterText, normalizeMode, appendLocalTelemetry, isSafeInRepoRead,
|
|
4579
|
-
loadSynkroFile, effectiveGraderPool,
|
|
4641
|
+
loadSynkroFile, effectiveGraderPool, synkroFilePresent, noSynkroSkipMessage,
|
|
4580
4642
|
hashCommand, resolveTranscriptPath, isCursorHookFormat,
|
|
4581
4643
|
type HookConfig, type Rule,
|
|
4582
4644
|
} from './_synkro-common.ts';
|
|
@@ -4657,6 +4719,13 @@ async function main() {
|
|
|
4657
4719
|
|
|
4658
4720
|
const gitRepo = detectRepo(cwd, transcriptPath, command, workspaceRoots);
|
|
4659
4721
|
|
|
4722
|
+
if (!synkroFilePresent(cwd)) {
|
|
4723
|
+
const _skipMsg = noSynkroSkipMessage(sessionId);
|
|
4724
|
+
if (_skipMsg) outputJson({ systemMessage: _skipMsg, hookSpecificOutput: { hookEventName: 'PreToolUse', additionalContext: _skipMsg } });
|
|
4725
|
+
else outputEmpty();
|
|
4726
|
+
return;
|
|
4727
|
+
}
|
|
4728
|
+
|
|
4660
4729
|
if (isDuplicate(command, sessionId)) {
|
|
4661
4730
|
log('bashGuard skip (dedup): ' + command.slice(0, 80));
|
|
4662
4731
|
outputEmpty();
|
|
@@ -4874,7 +4943,7 @@ import {
|
|
|
4874
4943
|
extractTranscript, readLastPrompt, appendSessionAction, readSessionLog, compressSessionLog, log,
|
|
4875
4944
|
outputJson, outputEmpty, setupCursorHookSignals, installHookWatchdog, isAgentTool, hookSessionId, GATEWAY_URL,
|
|
4876
4945
|
logGraderUnavailable, graderUnavailableMessage, filterRules, normalizeMode, resolveTranscriptPath, isCursorInvokingCcHook,
|
|
4877
|
-
loadSynkroFile, effectiveGraderPool,
|
|
4946
|
+
loadSynkroFile, effectiveGraderPool, synkroFilePresent, noSynkroSkipMessage,
|
|
4878
4947
|
type HookConfig, type Rule,
|
|
4879
4948
|
} from './_synkro-common.ts';
|
|
4880
4949
|
|
|
@@ -4905,6 +4974,13 @@ async function main() {
|
|
|
4905
4974
|
const permissionMode = payload.permission_mode || '';
|
|
4906
4975
|
const transcriptPath = resolveTranscriptPath(payload);
|
|
4907
4976
|
|
|
4977
|
+
if (!synkroFilePresent(cwd)) {
|
|
4978
|
+
const _skipMsg = noSynkroSkipMessage(sessionId);
|
|
4979
|
+
if (_skipMsg) outputJson({ systemMessage: _skipMsg, hookSpecificOutput: { hookEventName: 'PreToolUse', additionalContext: _skipMsg } });
|
|
4980
|
+
else outputEmpty();
|
|
4981
|
+
return;
|
|
4982
|
+
}
|
|
4983
|
+
|
|
4908
4984
|
const prompt = toolInput.prompt || '';
|
|
4909
4985
|
const description = toolInput.description || '';
|
|
4910
4986
|
const subagentType = toolInput.subagent_type || 'general-purpose';
|
|
@@ -5062,7 +5138,7 @@ import {
|
|
|
5062
5138
|
parseVerdict, dispatchCapture, appendSessionAction, readSessionLog, compressSessionLog, postWithRetry, readStdin, log,
|
|
5063
5139
|
outputJson, outputEmpty, setupCursorHookSignals, installHookWatchdog, isPlanTool, hookSessionId, GATEWAY_URL,
|
|
5064
5140
|
filterRules, graderUnavailableMessage, resolveTranscriptPath, isCursorInvokingCcHook,
|
|
5065
|
-
loadSynkroFile, effectiveGraderPool,
|
|
5141
|
+
loadSynkroFile, effectiveGraderPool, synkroFilePresent, noSynkroSkipMessage,
|
|
5066
5142
|
} from './_synkro-common.ts';
|
|
5067
5143
|
import { existsSync, readFileSync, writeFileSync, readdirSync, statSync } from 'node:fs';
|
|
5068
5144
|
import { join } from 'node:path';
|
|
@@ -5135,6 +5211,13 @@ async function main() {
|
|
|
5135
5211
|
const transcriptPath = resolveTranscriptPath(payload);
|
|
5136
5212
|
const gitRepo = detectRepo(cwd, transcriptPath, plan, workspaceRoots);
|
|
5137
5213
|
|
|
5214
|
+
if (!synkroFilePresent(cwd)) {
|
|
5215
|
+
const _skipMsg = noSynkroSkipMessage(sessionId);
|
|
5216
|
+
if (_skipMsg) outputJson({ systemMessage: _skipMsg, hookSpecificOutput: { hookEventName: 'PreToolUse', additionalContext: _skipMsg } });
|
|
5217
|
+
else outputEmpty();
|
|
5218
|
+
return;
|
|
5219
|
+
}
|
|
5220
|
+
|
|
5138
5221
|
appendSessionAction(sessionId, { ts: new Date().toISOString(), tool: 'ExitPlanMode', summary: 'plan review: ' + plan.slice(0, 80) });
|
|
5139
5222
|
|
|
5140
5223
|
const planShort = plan.slice(0, 80);
|
|
@@ -5249,7 +5332,7 @@ main();
|
|
|
5249
5332
|
import {
|
|
5250
5333
|
loadJwt, detectRepo, loadConfig, tag, readStdin, aggregateUsage, cleanupSessionLog,
|
|
5251
5334
|
outputJson, outputEmpty, shipCloud, setupCursorHookSignals, hookSessionId, GATEWAY_URL,
|
|
5252
|
-
resolveTranscriptPath, emitUsageTick, cursorModelFromPayload, log,
|
|
5335
|
+
resolveTranscriptPath, emitUsageTick, cursorModelFromPayload, log, synkroFilePresent,
|
|
5253
5336
|
} from './_synkro-common.ts';
|
|
5254
5337
|
|
|
5255
5338
|
async function main() {
|
|
@@ -5264,6 +5347,7 @@ async function main() {
|
|
|
5264
5347
|
|
|
5265
5348
|
const workspaceRoots = Array.isArray(payload.workspace_roots) ? payload.workspace_roots as string[] : [];
|
|
5266
5349
|
const cwd = payload.cwd || workspaceRoots[0] || '';
|
|
5350
|
+
if (!synkroFilePresent(cwd)) { outputEmpty(); return; }
|
|
5267
5351
|
const transcriptPath = resolveTranscriptPath(payload);
|
|
5268
5352
|
const gitRepo = detectRepo(cwd, transcriptPath, '', workspaceRoots);
|
|
5269
5353
|
const modelFallback = cursorModelFromPayload(payload);
|
|
@@ -5317,7 +5401,7 @@ main();
|
|
|
5317
5401
|
import {
|
|
5318
5402
|
loadJwt, detectRepo, channelUp, tag, readStdin, writeCachedRepo,
|
|
5319
5403
|
outputJson, outputEmpty, setupCursorHookSignals, hookSessionId, resolveTranscriptPath, GATEWAY_URL,
|
|
5320
|
-
isLocalStorageMode, loadSynkroFile, log, type HookConfig,
|
|
5404
|
+
isLocalStorageMode, loadSynkroFile, log, synkroFilePresent, type HookConfig,
|
|
5321
5405
|
} from './_synkro-common.ts';
|
|
5322
5406
|
|
|
5323
5407
|
async function main() {
|
|
@@ -5329,6 +5413,7 @@ async function main() {
|
|
|
5329
5413
|
const payload = JSON.parse(input);
|
|
5330
5414
|
const workspaceRoots = Array.isArray(payload.workspace_roots) ? payload.workspace_roots as string[] : [];
|
|
5331
5415
|
const cwd = payload.cwd || workspaceRoots[0] || '';
|
|
5416
|
+
if (!synkroFilePresent(cwd)) { outputEmpty(); return; }
|
|
5332
5417
|
const transcriptPath = resolveTranscriptPath(payload);
|
|
5333
5418
|
const sessionId = hookSessionId(payload);
|
|
5334
5419
|
const gitRepo = detectRepo(cwd, transcriptPath, '', workspaceRoots);
|
|
@@ -5408,7 +5493,7 @@ main();
|
|
|
5408
5493
|
import {
|
|
5409
5494
|
loadJwt, loadConfig, readStdin, hashCommand, consentGrant, consentHasActive, consentConsume,
|
|
5410
5495
|
appendSessionAction,
|
|
5411
|
-
outputEmpty, appendLocalTelemetry, shipCloud, setupCursorHookSignals, isShellTool, hookSessionId, GATEWAY_URL,
|
|
5496
|
+
outputEmpty, appendLocalTelemetry, shipCloud, setupCursorHookSignals, isShellTool, hookSessionId, GATEWAY_URL, synkroFilePresent,
|
|
5412
5497
|
} from './_synkro-common.ts';
|
|
5413
5498
|
|
|
5414
5499
|
async function main() {
|
|
@@ -5418,6 +5503,8 @@ async function main() {
|
|
|
5418
5503
|
if (!input.trim()) { outputEmpty(); return; }
|
|
5419
5504
|
|
|
5420
5505
|
const payload = JSON.parse(input);
|
|
5506
|
+
const _cwd = payload.cwd || (Array.isArray(payload.workspace_roots) ? payload.workspace_roots[0] : '') || '';
|
|
5507
|
+
if (!synkroFilePresent(_cwd)) { outputEmpty(); return; }
|
|
5421
5508
|
const toolName = payload.tool_name || '';
|
|
5422
5509
|
const shellCmd = typeof payload.command === 'string' ? payload.command : (payload.tool_input?.command || '');
|
|
5423
5510
|
if (!isShellTool(toolName) && !shellCmd) { outputEmpty(); return; }
|
|
@@ -5472,7 +5559,7 @@ main();
|
|
|
5472
5559
|
import {
|
|
5473
5560
|
loadJwt, detectRepo, readStdin, aggregateUsage, appendLocalTelemetry,
|
|
5474
5561
|
outputEmpty, setupCursorHookSignals, hookSessionId, GATEWAY_URL, readSessionLog, shipCloud,
|
|
5475
|
-
resolveTranscriptPath, syncConversationTranscript, emitUsageTick, cursorModelFromPayload,
|
|
5562
|
+
resolveTranscriptPath, syncConversationTranscript, emitUsageTick, cursorModelFromPayload, synkroFilePresent,
|
|
5476
5563
|
} from './_synkro-common.ts';
|
|
5477
5564
|
import { readFileSync } from 'node:fs';
|
|
5478
5565
|
|
|
@@ -5486,6 +5573,7 @@ async function main() {
|
|
|
5486
5573
|
const sessionId = hookSessionId(payload);
|
|
5487
5574
|
const workspaceRoots = Array.isArray(payload.workspace_roots) ? payload.workspace_roots as string[] : [];
|
|
5488
5575
|
const cwd = payload.cwd || workspaceRoots[0] || '';
|
|
5576
|
+
if (!synkroFilePresent(cwd)) { outputEmpty(); return; }
|
|
5489
5577
|
const transcriptPath = resolveTranscriptPath(payload);
|
|
5490
5578
|
|
|
5491
5579
|
if (!sessionId || !transcriptPath) {
|
|
@@ -5531,7 +5619,7 @@ async function main() {
|
|
|
5531
5619
|
main();
|
|
5532
5620
|
`;
|
|
5533
5621
|
USER_PROMPT_SUBMIT_TS = `#!/usr/bin/env bun
|
|
5534
|
-
import { readStdin, appendLocalTelemetry, aggregateUsage, outputEmpty, setupCursorHookSignals, hookSessionId, detectRepo, resolveTranscriptPath, syncConversationTranscript, emitUsageTick, cursorModelFromPayload } from './_synkro-common.ts';
|
|
5622
|
+
import { readStdin, appendLocalTelemetry, aggregateUsage, outputEmpty, setupCursorHookSignals, hookSessionId, detectRepo, resolveTranscriptPath, syncConversationTranscript, emitUsageTick, cursorModelFromPayload, synkroFilePresent } from './_synkro-common.ts';
|
|
5535
5623
|
import { writeFileSync, mkdirSync } from 'node:fs';
|
|
5536
5624
|
import { join, dirname } from 'node:path';
|
|
5537
5625
|
import { homedir } from 'node:os';
|
|
@@ -5542,7 +5630,12 @@ async function main() {
|
|
|
5542
5630
|
const input = await readStdin();
|
|
5543
5631
|
if (!input.trim()) { outputEmpty(); return; }
|
|
5544
5632
|
const payload = JSON.parse(input);
|
|
5545
|
-
const
|
|
5633
|
+
const _cwd = typeof payload.cwd === 'string' ? payload.cwd
|
|
5634
|
+
: (Array.isArray(payload.workspace_roots) && typeof payload.workspace_roots[0] === 'string' ? payload.workspace_roots[0] : '');
|
|
5635
|
+
if (!synkroFilePresent(_cwd)) { outputEmpty(); return; }
|
|
5636
|
+
const msg = typeof payload.message === 'string' ? payload.message
|
|
5637
|
+
: typeof payload.prompt === 'string' ? payload.prompt
|
|
5638
|
+
: typeof payload.content === 'string' ? payload.content : '';
|
|
5546
5639
|
if (msg) {
|
|
5547
5640
|
const promptFile = join(homedir(), '.synkro', '.last-prompt');
|
|
5548
5641
|
mkdirSync(dirname(promptFile), { recursive: true, mode: 0o700 });
|
|
@@ -5581,7 +5674,7 @@ import {
|
|
|
5581
5674
|
isSafeInRepoRead, resolveTranscriptPath, postWithRetry, readStdin, hashCommand,
|
|
5582
5675
|
extractTranscript, readLastPrompt, readSessionLog, compressSessionLog,
|
|
5583
5676
|
appendLocalTelemetry, logGraderUnavailable, graderUnavailableMessage, log, GATEWAY_URL,
|
|
5584
|
-
loadSynkroFile, effectiveGraderPool,
|
|
5677
|
+
loadSynkroFile, effectiveGraderPool, synkroFilePresent,
|
|
5585
5678
|
type Rule,
|
|
5586
5679
|
} from './_synkro-common.ts';
|
|
5587
5680
|
import { createHash } from 'node:crypto';
|
|
@@ -5699,6 +5792,10 @@ async function main() {
|
|
|
5699
5792
|
const model = rawModel ? (rawModel.startsWith('cursor/') ? rawModel : 'cursor/' + rawModel) : 'cursor';
|
|
5700
5793
|
const repo = detectRepo(cwd, transcriptPath, command, workspaceRoots);
|
|
5701
5794
|
|
|
5795
|
+
// No .synkro at the resolved repo root \u2192 Synkro is dormant here; allow
|
|
5796
|
+
// without grading. Keyed off the validated detectRepo() root, not raw cwd.
|
|
5797
|
+
if (!repo || !synkroFilePresent(repo)) finishAllow();
|
|
5798
|
+
|
|
5702
5799
|
const cmdShort = command.slice(0, 80);
|
|
5703
5800
|
log('bashGuard checking: ' + cmdShort);
|
|
5704
5801
|
|
|
@@ -5882,7 +5979,7 @@ import {
|
|
|
5882
5979
|
loadJwt, ensureFreshJwt, detectRepo, readStdin, resolveTranscriptPath,
|
|
5883
5980
|
appendSessionAction, appendLocalTelemetry, shipCloud, log, GATEWAY_URL,
|
|
5884
5981
|
countEditLineDelta, dispatchCapture, hookSessionId, cursorModelFromPayload,
|
|
5885
|
-
isLocalStorageMode,
|
|
5982
|
+
isLocalStorageMode, synkroFilePresent, isPathUnder,
|
|
5886
5983
|
} from './_synkro-common.ts';
|
|
5887
5984
|
import { existsSync, readFileSync } from 'node:fs';
|
|
5888
5985
|
import { basename, dirname, join } from 'node:path';
|
|
@@ -5908,6 +6005,10 @@ async function main() {
|
|
|
5908
6005
|
const filePath = String(payload.file_path || payload.path || payload.target_file || '');
|
|
5909
6006
|
if (!filePath) finish();
|
|
5910
6007
|
|
|
6008
|
+
// No .synkro at the resolved repo root \u2192 Synkro is dormant here; skip capture.
|
|
6009
|
+
const _root = detectRepo((typeof payload.cwd === 'string' && payload.cwd) || dirname(filePath), '', filePath, []);
|
|
6010
|
+
if (!_root || !isPathUnder(filePath, _root) || !synkroFilePresent(_root)) finish();
|
|
6011
|
+
|
|
5911
6012
|
const workspaceRoots = Array.isArray(payload.workspace_roots)
|
|
5912
6013
|
? (payload.workspace_roots as unknown[]).filter((r): r is string => typeof r === 'string')
|
|
5913
6014
|
: [];
|
|
@@ -6010,7 +6111,7 @@ main().catch((e) => {
|
|
|
6010
6111
|
/** Capture Cursor agent thinking/response text before transcript JSONL redacts it. */
|
|
6011
6112
|
import {
|
|
6012
6113
|
readStdin, outputEmpty, setupCursorHookSignals, hookSessionId, detectRepo,
|
|
6013
|
-
appendThoughtOverlay, pushConversationMessage,
|
|
6114
|
+
appendThoughtOverlay, pushConversationMessage, synkroFilePresent,
|
|
6014
6115
|
} from './_synkro-common.ts';
|
|
6015
6116
|
|
|
6016
6117
|
async function main() {
|
|
@@ -6030,6 +6131,7 @@ async function main() {
|
|
|
6030
6131
|
? payload.workspace_roots.filter((r): r is string => typeof r === 'string')
|
|
6031
6132
|
: [];
|
|
6032
6133
|
const cwd = (typeof payload.cwd === 'string' && payload.cwd) || workspaceRoots[0] || '';
|
|
6134
|
+
if (!synkroFilePresent(cwd)) { outputEmpty(); return; }
|
|
6033
6135
|
const gitRepo = detectRepo(cwd, '', '', workspaceRoots);
|
|
6034
6136
|
|
|
6035
6137
|
if (event === 'afterAgentThought') {
|
|
@@ -8301,7 +8403,7 @@ function writeConfigEnv(opts) {
|
|
|
8301
8403
|
`SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
|
|
8302
8404
|
`SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
|
|
8303
8405
|
`SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
|
|
8304
|
-
`SYNKRO_VERSION=${shellQuoteSingle("1.6.
|
|
8406
|
+
`SYNKRO_VERSION=${shellQuoteSingle("1.6.46")}`
|
|
8305
8407
|
];
|
|
8306
8408
|
if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle(safeSynkroBin)}`);
|
|
8307
8409
|
if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
|
|
@@ -11386,7 +11488,7 @@ var args = process.argv.slice(2);
|
|
|
11386
11488
|
var cmd = args[0] || "";
|
|
11387
11489
|
var subArgs = args.slice(1);
|
|
11388
11490
|
function printVersion() {
|
|
11389
|
-
console.log("1.6.
|
|
11491
|
+
console.log("1.6.46");
|
|
11390
11492
|
}
|
|
11391
11493
|
function printHelp2() {
|
|
11392
11494
|
console.log(`Synkro CLI \u2014 runtime safety for AI coding agents
|