@synkro-sh/cli 1.6.32 → 1.6.33
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 +139 -6
- package/dist/bootstrap.js.map +1 -1
- package/package.json +1 -1
package/dist/bootstrap.js
CHANGED
|
@@ -1144,6 +1144,7 @@ export function findGitRoot(cwd: string): string {
|
|
|
1144
1144
|
|
|
1145
1145
|
export interface SynkroFileConfig {
|
|
1146
1146
|
version: number;
|
|
1147
|
+
harness: ('claude-code' | 'cursor')[];
|
|
1147
1148
|
grader: { pool: 'auto' | 'claude' | 'cursor'; mode?: string };
|
|
1148
1149
|
ruleset: string;
|
|
1149
1150
|
scanning: { cwe: boolean; cve: boolean };
|
|
@@ -1151,6 +1152,7 @@ export interface SynkroFileConfig {
|
|
|
1151
1152
|
|
|
1152
1153
|
const SYNKRO_FILE_DEFAULTS: SynkroFileConfig = {
|
|
1153
1154
|
version: 1,
|
|
1155
|
+
harness: ['claude-code', 'cursor'],
|
|
1154
1156
|
grader: { pool: 'auto' },
|
|
1155
1157
|
ruleset: 'default',
|
|
1156
1158
|
scanning: { cwe: true, cve: true },
|
|
@@ -1166,8 +1168,13 @@ export function loadSynkroFile(cwd?: string): SynkroFileConfig {
|
|
|
1166
1168
|
try {
|
|
1167
1169
|
if (!existsSync(fp)) { _synkroFileCache = SYNKRO_FILE_DEFAULTS; return _synkroFileCache; }
|
|
1168
1170
|
const parsed = JSON.parse(readFileSync(fp, 'utf-8'));
|
|
1171
|
+
const validHarness = ['claude-code', 'cursor'] as const;
|
|
1172
|
+
const harness = Array.isArray(parsed.harness)
|
|
1173
|
+
? parsed.harness.filter((h: string) => validHarness.includes(h as any))
|
|
1174
|
+
: ['claude-code', 'cursor'];
|
|
1169
1175
|
_synkroFileCache = {
|
|
1170
1176
|
version: parsed.version || 1,
|
|
1177
|
+
harness: harness.length > 0 ? harness : ['claude-code', 'cursor'],
|
|
1171
1178
|
grader: {
|
|
1172
1179
|
pool: ['auto', 'claude', 'cursor'].includes(parsed.grader?.pool) ? parsed.grader.pool : 'auto',
|
|
1173
1180
|
mode: ['local', 'byok'].includes(parsed.grader?.mode) ? parsed.grader.mode : undefined,
|
|
@@ -7865,7 +7872,9 @@ var install_exports = {};
|
|
|
7865
7872
|
__export(install_exports, {
|
|
7866
7873
|
detectGitRepo: () => detectGitRepo2,
|
|
7867
7874
|
installCommand: () => installCommand,
|
|
7868
|
-
parseArgs: () => parseArgs
|
|
7875
|
+
parseArgs: () => parseArgs,
|
|
7876
|
+
reconcileHarness: () => reconcileHarness,
|
|
7877
|
+
writeHookScripts: () => writeHookScripts
|
|
7869
7878
|
});
|
|
7870
7879
|
import { existsSync as existsSync9, mkdirSync as mkdirSync8, writeFileSync as writeFileSync7, chmodSync as chmodSync2, readFileSync as readFileSync8, readdirSync as readdirSync3 } from "fs";
|
|
7871
7880
|
import { homedir as homedir8 } from "os";
|
|
@@ -8113,7 +8122,7 @@ function writeConfigEnv(opts) {
|
|
|
8113
8122
|
`SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
|
|
8114
8123
|
`SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
|
|
8115
8124
|
`SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
|
|
8116
|
-
`SYNKRO_VERSION=${shellQuoteSingle("1.6.
|
|
8125
|
+
`SYNKRO_VERSION=${shellQuoteSingle("1.6.33")}`
|
|
8117
8126
|
];
|
|
8118
8127
|
if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle(safeSynkroBin)}`);
|
|
8119
8128
|
if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
|
|
@@ -8648,10 +8657,18 @@ function writeSynkroFileIfMissing(opts) {
|
|
|
8648
8657
|
return;
|
|
8649
8658
|
}
|
|
8650
8659
|
let pool = "auto";
|
|
8651
|
-
|
|
8652
|
-
|
|
8660
|
+
const harness = [];
|
|
8661
|
+
if (opts.hasClaudeCode) {
|
|
8662
|
+
harness.push("claude-code");
|
|
8663
|
+
if (!opts.hasCursor) pool = "claude";
|
|
8664
|
+
}
|
|
8665
|
+
if (opts.hasCursor) {
|
|
8666
|
+
harness.push("cursor");
|
|
8667
|
+
if (!opts.hasClaudeCode) pool = "cursor";
|
|
8668
|
+
}
|
|
8653
8669
|
const config = {
|
|
8654
8670
|
version: 1,
|
|
8671
|
+
harness,
|
|
8655
8672
|
grader: {
|
|
8656
8673
|
pool,
|
|
8657
8674
|
mode: opts.gradingMode === "byok" ? "byok" : "local"
|
|
@@ -8677,6 +8694,109 @@ function readSynkroFilePool2() {
|
|
|
8677
8694
|
}
|
|
8678
8695
|
return "auto";
|
|
8679
8696
|
}
|
|
8697
|
+
function readFullSynkroFile() {
|
|
8698
|
+
try {
|
|
8699
|
+
const root = execSync6("git rev-parse --show-toplevel", { encoding: "utf-8", timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
8700
|
+
if (!root) return null;
|
|
8701
|
+
const fp = join8(root, ".synkro");
|
|
8702
|
+
if (!existsSync9(fp)) return null;
|
|
8703
|
+
const parsed = JSON.parse(readFileSync8(fp, "utf-8"));
|
|
8704
|
+
const valid = ["claude-code", "cursor"];
|
|
8705
|
+
const harness = Array.isArray(parsed.harness) ? parsed.harness.filter((h) => valid.includes(h)) : ["claude-code", "cursor"];
|
|
8706
|
+
return {
|
|
8707
|
+
harness: harness.length > 0 ? harness : ["claude-code", "cursor"],
|
|
8708
|
+
grader: {
|
|
8709
|
+
pool: ["auto", "claude", "cursor"].includes(parsed.grader?.pool) ? parsed.grader.pool : "auto",
|
|
8710
|
+
mode: ["local", "byok"].includes(parsed.grader?.mode) ? parsed.grader.mode : "local"
|
|
8711
|
+
},
|
|
8712
|
+
ruleset: parsed.ruleset || "default",
|
|
8713
|
+
scanning: { cwe: parsed.scanning?.cwe !== false, cve: parsed.scanning?.cve !== false }
|
|
8714
|
+
};
|
|
8715
|
+
} catch {
|
|
8716
|
+
return null;
|
|
8717
|
+
}
|
|
8718
|
+
}
|
|
8719
|
+
function reconcileHarness() {
|
|
8720
|
+
const sf = readFullSynkroFile();
|
|
8721
|
+
if (!sf) {
|
|
8722
|
+
console.log("No .synkro file found in repo root \u2014 skipping harness reconciliation.");
|
|
8723
|
+
return null;
|
|
8724
|
+
}
|
|
8725
|
+
const wantCC = sf.harness.includes("claude-code");
|
|
8726
|
+
const wantCursor = sf.harness.includes("cursor");
|
|
8727
|
+
console.log(`.synkro: harness=[${sf.harness.join(", ")}] pool=${sf.grader.pool} mode=${sf.grader.mode}`);
|
|
8728
|
+
const scripts = writeHookScripts();
|
|
8729
|
+
console.log("Wrote hook scripts to ~/.synkro/hooks/");
|
|
8730
|
+
const ccSettings = join8(homedir8(), ".claude", "settings.json");
|
|
8731
|
+
if (wantCC) {
|
|
8732
|
+
installCCHooks(ccSettings, {
|
|
8733
|
+
bashJudgeScriptPath: scripts.bashScript,
|
|
8734
|
+
bashFollowupScriptPath: scripts.bashFollowupScript,
|
|
8735
|
+
editPrecheckScriptPath: scripts.editPrecheckScript,
|
|
8736
|
+
cwePrecheckScriptPath: scripts.cwePrecheckScript,
|
|
8737
|
+
cvePrecheckScriptPath: scripts.cvePrecheckScript,
|
|
8738
|
+
planJudgeScriptPath: scripts.planJudgeScript,
|
|
8739
|
+
agentJudgeScriptPath: scripts.agentJudgeScript,
|
|
8740
|
+
stopSummaryScriptPath: scripts.stopSummaryScript,
|
|
8741
|
+
sessionStartScriptPath: scripts.sessionStartScript,
|
|
8742
|
+
transcriptSyncScriptPath: scripts.transcriptSyncScript,
|
|
8743
|
+
userPromptSubmitScriptPath: scripts.userPromptSubmitScript,
|
|
8744
|
+
installScanScriptPath: scripts.installScanScript
|
|
8745
|
+
});
|
|
8746
|
+
console.log(" \u2713 Claude Code hooks registered");
|
|
8747
|
+
try {
|
|
8748
|
+
const mcpJwt = readFileSync8(join8(SYNKRO_DIR4, ".mcp-jwt"), "utf-8").trim();
|
|
8749
|
+
if (mcpJwt) {
|
|
8750
|
+
installMcpConfig({ gatewayUrl: "", bearerToken: mcpJwt, local: true });
|
|
8751
|
+
console.log(" \u2713 Claude Code MCP registered");
|
|
8752
|
+
}
|
|
8753
|
+
} catch {
|
|
8754
|
+
}
|
|
8755
|
+
} else {
|
|
8756
|
+
if (uninstallCCHooks(ccSettings)) console.log(" \u2717 Claude Code hooks removed");
|
|
8757
|
+
if (uninstallMcpConfig()) console.log(" \u2717 Claude Code MCP removed");
|
|
8758
|
+
}
|
|
8759
|
+
const cursorHooks = join8(homedir8(), ".cursor", "hooks.json");
|
|
8760
|
+
if (wantCursor) {
|
|
8761
|
+
installCursorHooks(cursorHooks, {
|
|
8762
|
+
bashJudgeScriptPath: scripts.cursorBashJudgeScript,
|
|
8763
|
+
editCaptureScriptPath: scripts.cursorEditCaptureScript,
|
|
8764
|
+
agentCaptureScriptPath: scripts.cursorAgentCaptureScript,
|
|
8765
|
+
bashFollowupScriptPath: scripts.bashFollowupScript,
|
|
8766
|
+
editPrecheckScriptPath: scripts.editPrecheckScript,
|
|
8767
|
+
cwePrecheckScriptPath: scripts.cwePrecheckScript,
|
|
8768
|
+
cvePrecheckScriptPath: scripts.cvePrecheckScript,
|
|
8769
|
+
planJudgeScriptPath: scripts.planJudgeScript,
|
|
8770
|
+
agentJudgeScriptPath: scripts.agentJudgeScript,
|
|
8771
|
+
stopSummaryScriptPath: scripts.stopSummaryScript,
|
|
8772
|
+
sessionStartScriptPath: scripts.sessionStartScript,
|
|
8773
|
+
userPromptSubmitScriptPath: scripts.userPromptSubmitScript,
|
|
8774
|
+
transcriptSyncScriptPath: scripts.transcriptSyncScript,
|
|
8775
|
+
installScanScriptPath: scripts.installScanScript
|
|
8776
|
+
});
|
|
8777
|
+
console.log(" \u2713 Cursor hooks registered");
|
|
8778
|
+
try {
|
|
8779
|
+
installCursorMcpConfig({ gatewayUrl: "", bearerToken: "", local: true });
|
|
8780
|
+
console.log(" \u2713 Cursor MCP registered");
|
|
8781
|
+
} catch {
|
|
8782
|
+
}
|
|
8783
|
+
} else {
|
|
8784
|
+
if (uninstallCursorHooks(cursorHooks)) console.log(" \u2717 Cursor hooks removed");
|
|
8785
|
+
if (uninstallCursorMcpConfig()) console.log(" \u2717 Cursor MCP removed");
|
|
8786
|
+
}
|
|
8787
|
+
const total = parseInt(process.env.SYNKRO_WORKERS_PER_POOL || "8", 10);
|
|
8788
|
+
const providers = [];
|
|
8789
|
+
if (sf.grader.pool === "cursor") {
|
|
8790
|
+
providers.push("cursor");
|
|
8791
|
+
} else if (sf.grader.pool === "claude") {
|
|
8792
|
+
providers.push("claude_code");
|
|
8793
|
+
} else {
|
|
8794
|
+
if (wantCC) providers.push("claude_code");
|
|
8795
|
+
if (wantCursor) providers.push("cursor");
|
|
8796
|
+
}
|
|
8797
|
+
if (providers.length === 0) providers.push("claude_code");
|
|
8798
|
+
return splitWorkers(total, providers);
|
|
8799
|
+
}
|
|
8680
8800
|
function detectGitRepo2() {
|
|
8681
8801
|
const run = (cmd2) => {
|
|
8682
8802
|
try {
|
|
@@ -10400,7 +10520,19 @@ function cmdStop() {
|
|
|
10400
10520
|
}
|
|
10401
10521
|
async function cmdRestart(rest = []) {
|
|
10402
10522
|
if (inDockerMode()) {
|
|
10403
|
-
const {
|
|
10523
|
+
const { explicit } = resolveWorkerConfig(rest);
|
|
10524
|
+
let claudeWorkers;
|
|
10525
|
+
let cursorWorkers;
|
|
10526
|
+
if (explicit) {
|
|
10527
|
+
({ claudeWorkers, cursorWorkers } = resolveWorkerConfig(rest));
|
|
10528
|
+
} else {
|
|
10529
|
+
const reconciled = reconcileHarness();
|
|
10530
|
+
if (reconciled) {
|
|
10531
|
+
({ claudeWorkers, cursorWorkers } = reconciled);
|
|
10532
|
+
} else {
|
|
10533
|
+
({ claudeWorkers, cursorWorkers } = resolveWorkerConfig(rest));
|
|
10534
|
+
}
|
|
10535
|
+
}
|
|
10404
10536
|
console.log(`Restarting synkro-server container (${claudeWorkers} claude + ${cursorWorkers} cursor, pulling latest image)...`);
|
|
10405
10537
|
await dockerUpdate({ claudeWorkers, cursorWorkers });
|
|
10406
10538
|
const ready = await waitForContainerReady(6e4);
|
|
@@ -10644,6 +10776,7 @@ var init_localCc = __esm({
|
|
|
10644
10776
|
init_settings();
|
|
10645
10777
|
init_macKeychain();
|
|
10646
10778
|
init_dockerInstall();
|
|
10779
|
+
init_install();
|
|
10647
10780
|
init_client();
|
|
10648
10781
|
init_stub();
|
|
10649
10782
|
SYNKRO_CONFIG_PATH = join14(homedir14(), ".synkro", "config.env");
|
|
@@ -10922,7 +11055,7 @@ var args = process.argv.slice(2);
|
|
|
10922
11055
|
var cmd = args[0] || "";
|
|
10923
11056
|
var subArgs = args.slice(1);
|
|
10924
11057
|
function printVersion() {
|
|
10925
|
-
console.log("1.6.
|
|
11058
|
+
console.log("1.6.33");
|
|
10926
11059
|
}
|
|
10927
11060
|
function printHelp2() {
|
|
10928
11061
|
console.log(`Synkro CLI \u2014 runtime safety for AI coding agents
|