@synkro-sh/cli 1.7.89 → 1.7.90
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 +110 -10
- package/dist/bootstrap.js.map +1 -1
- package/package.json +1 -1
package/dist/bootstrap.js
CHANGED
|
@@ -147,7 +147,7 @@ function getIdentity() {
|
|
|
147
147
|
if (cached2) return cached2;
|
|
148
148
|
let cliVersion = "0.0.0";
|
|
149
149
|
try {
|
|
150
|
-
cliVersion = "1.7.
|
|
150
|
+
cliVersion = "1.7.90";
|
|
151
151
|
} catch {
|
|
152
152
|
}
|
|
153
153
|
const creds = loadCredentialsIdentity();
|
|
@@ -2117,7 +2117,11 @@ function installCodexHooks(hooksJsonPath, config) {
|
|
|
2117
2117
|
push(h, "SubagentStart", [cmd(config.subagentStartScriptPath, 5)]);
|
|
2118
2118
|
if (!config.skipTranscriptSync) push(h, "SubagentStop", [cmd(config.subagentStopScriptPath, 5)]);
|
|
2119
2119
|
push(h, "SessionEnd", [cmd(config.stopSummaryScriptPath, 3)]);
|
|
2120
|
-
|
|
2120
|
+
push(h, "Stop", [
|
|
2121
|
+
cmd(config.cweStopScriptPath, 50, "Checking completed edits for weaknesses"),
|
|
2122
|
+
cmd(config.cveStopScriptPath, 50, "Checking completed edits for vulnerabilities"),
|
|
2123
|
+
...!config.skipTranscriptSync ? [cmd(config.transcriptSyncScriptPath, 3)] : []
|
|
2124
|
+
]);
|
|
2121
2125
|
writeHooksFileAtomic2(hooksJsonPath, file);
|
|
2122
2126
|
}
|
|
2123
2127
|
function uninstallCodexHooks(hooksJsonPath) {
|
|
@@ -2540,7 +2544,7 @@ var init_skillParser = __esm({
|
|
|
2540
2544
|
function stubHook(surface, optsLiteral) {
|
|
2541
2545
|
return "#!/usr/bin/env bun\nimport { runStub } from './_synkro-stub-common.ts';\nrunStub(" + JSON.stringify(surface) + ", " + optsLiteral + ");\n";
|
|
2542
2546
|
}
|
|
2543
|
-
var STUB_COMMON_TS, STUB_EDIT_PRECHECK_TS, STUB_EDIT_FOLLOWUP_TS, STUB_CWE_PRECHECK_TS, STUB_CVE_PRECHECK_TS, STUB_BASH_JUDGE_TS, STUB_SKILL_JUDGE_TS, STUB_INSTALL_SCAN_TS, STUB_AGENT_JUDGE_TS, STUB_MCP_GATE_TS, STUB_PLAN_JUDGE_TS, STUB_STOP_SUMMARY_TS, STUB_SESSION_START_TS, STUB_TRANSCRIPT_SYNC_TS, STUB_SUBAGENT_START_TS, STUB_SUBAGENT_STOP_TS, STUB_USER_PROMPT_SUBMIT_TS, STUB_BASH_FOLLOWUP_TS, STUB_PROMPT_ROUTE_TS, STUB_TASK_ACTIVATE_INTENT_TS, STUB_CURSOR_BASH_JUDGE_TS, STUB_CURSOR_SKILL_JUDGE_TS, STUB_CURSOR_EDIT_CAPTURE_TS, STUB_CURSOR_AGENT_CAPTURE_TS;
|
|
2547
|
+
var STUB_COMMON_TS, STUB_EDIT_PRECHECK_TS, STUB_EDIT_FOLLOWUP_TS, STUB_CWE_PRECHECK_TS, STUB_CVE_PRECHECK_TS, STUB_BASH_JUDGE_TS, STUB_SKILL_JUDGE_TS, STUB_INSTALL_SCAN_TS, STUB_AGENT_JUDGE_TS, STUB_MCP_GATE_TS, STUB_PLAN_JUDGE_TS, STUB_STOP_SUMMARY_TS, STUB_SESSION_START_TS, STUB_TRANSCRIPT_SYNC_TS, STUB_CODEX_CWE_STOP_TS, STUB_CODEX_CVE_STOP_TS, STUB_SUBAGENT_START_TS, STUB_SUBAGENT_STOP_TS, STUB_USER_PROMPT_SUBMIT_TS, STUB_BASH_FOLLOWUP_TS, STUB_PROMPT_ROUTE_TS, STUB_TASK_ACTIVATE_INTENT_TS, STUB_CURSOR_BASH_JUDGE_TS, STUB_CURSOR_SKILL_JUDGE_TS, STUB_CURSOR_EDIT_CAPTURE_TS, STUB_CURSOR_AGENT_CAPTURE_TS;
|
|
2544
2548
|
var init_hookScriptsTs = __esm({
|
|
2545
2549
|
"cli/installer/hookScriptsTs.ts"() {
|
|
2546
2550
|
"use strict";
|
|
@@ -2752,6 +2756,28 @@ function failOpen(harness: string): string {
|
|
|
2752
2756
|
return harness === 'cursor' ? '{"permission":"allow"}' : '{}';
|
|
2753
2757
|
}
|
|
2754
2758
|
|
|
2759
|
+
/** Convert an existing security PreToolUse verdict into Codex's Stop contract. */
|
|
2760
|
+
export function codexStopResponse(responseText: string): string {
|
|
2761
|
+
try {
|
|
2762
|
+
const parsed = JSON.parse(responseText || '{}');
|
|
2763
|
+
const specific = parsed?.hookSpecificOutput;
|
|
2764
|
+
if (specific?.permissionDecision !== 'deny') return '{}';
|
|
2765
|
+
const reason = String(
|
|
2766
|
+
specific.permissionDecisionReason
|
|
2767
|
+
|| specific.additionalContext
|
|
2768
|
+
|| parsed.systemMessage
|
|
2769
|
+
|| 'A completed edit contains a CWE weakness. Fix it before stopping.',
|
|
2770
|
+
);
|
|
2771
|
+
return JSON.stringify({
|
|
2772
|
+
decision: 'block',
|
|
2773
|
+
reason,
|
|
2774
|
+
...(parsed.systemMessage ? { systemMessage: parsed.systemMessage } : {}),
|
|
2775
|
+
});
|
|
2776
|
+
} catch {
|
|
2777
|
+
return '{}';
|
|
2778
|
+
}
|
|
2779
|
+
}
|
|
2780
|
+
|
|
2755
2781
|
function out(s: string): void { try { process.stdout.write(s + '\n'); } catch {} }
|
|
2756
2782
|
|
|
2757
2783
|
function gitRoot(cwd: string): string {
|
|
@@ -3100,6 +3126,40 @@ export function extractCompletedCodexPatchEdits(
|
|
|
3100
3126
|
return results;
|
|
3101
3127
|
}
|
|
3102
3128
|
|
|
3129
|
+
/**
|
|
3130
|
+
* Recover only the latest completed apply_patch for each file in the current
|
|
3131
|
+
* Codex turn. Stop hooks may fire repeatedly while an agent self-corrects, so
|
|
3132
|
+
* scanning the latest on-disk state avoids re-blocking an earlier vulnerable
|
|
3133
|
+
* patch after a later patch fixed it.
|
|
3134
|
+
*/
|
|
3135
|
+
export function extractCompletedCodexTurnPatchEdits(
|
|
3136
|
+
transcript: string,
|
|
3137
|
+
repoRoot: string,
|
|
3138
|
+
): RecoveredCodexEdit[] {
|
|
3139
|
+
if (!transcript || !repoRoot) return [];
|
|
3140
|
+
const lines = transcript.split('\n');
|
|
3141
|
+
let latestUserLine = -1;
|
|
3142
|
+
for (let index = 0; index < lines.length; index++) {
|
|
3143
|
+
if (!lines[index].trim()) continue;
|
|
3144
|
+
let entry: any;
|
|
3145
|
+
try { entry = JSON.parse(lines[index]); } catch { continue; }
|
|
3146
|
+
const canonicalUser = entry?.type === 'event_msg'
|
|
3147
|
+
&& entry?.payload?.type === 'user_message';
|
|
3148
|
+
const compatibilityUser = entry?.type === 'response_item'
|
|
3149
|
+
&& entry?.payload?.type === 'message'
|
|
3150
|
+
&& entry?.payload?.role === 'user';
|
|
3151
|
+
if (canonicalUser || compatibilityUser) latestUserLine = index;
|
|
3152
|
+
}
|
|
3153
|
+
const turnTranscript = lines.slice(latestUserLine + 1).join('\n');
|
|
3154
|
+
const recovered = extractCompletedCodexPatchEdits(turnTranscript, repoRoot);
|
|
3155
|
+
const latestByFile = new Map<string, RecoveredCodexEdit>();
|
|
3156
|
+
for (const item of recovered) {
|
|
3157
|
+
const filePath = filePathFromToolInput(item.payload?.tool_input);
|
|
3158
|
+
if (filePath) latestByFile.set(filePath, item);
|
|
3159
|
+
}
|
|
3160
|
+
return [...latestByFile.values()];
|
|
3161
|
+
}
|
|
3162
|
+
|
|
3103
3163
|
interface StubOpts {
|
|
3104
3164
|
needsFile?: boolean;
|
|
3105
3165
|
needsTranscript?: boolean;
|
|
@@ -3110,6 +3170,10 @@ interface StubOpts {
|
|
|
3110
3170
|
telemetry?: boolean;
|
|
3111
3171
|
harness?: string;
|
|
3112
3172
|
postEdit?: boolean;
|
|
3173
|
+
/** Recover only this Codex turn's latest completed patch per file. */
|
|
3174
|
+
codexTurnEdits?: boolean;
|
|
3175
|
+
/** Translate a security PreToolUse deny into Codex's Stop block response. */
|
|
3176
|
+
stopContract?: boolean;
|
|
3113
3177
|
/** Codex SubagentStart/SubagentStop report the parent as session_id and
|
|
3114
3178
|
* the child as agent_id. Remap them to the ordinary child-session envelope. */
|
|
3115
3179
|
subagent?: boolean;
|
|
@@ -3361,12 +3425,33 @@ export async function runStub(surface: string, opts: StubOpts = {}): Promise<voi
|
|
|
3361
3425
|
const cap = opts.fullTranscript ? 400000 : 200000;
|
|
3362
3426
|
envelope.transcript = t.length <= cap ? t : t.slice(t.length - cap);
|
|
3363
3427
|
if (harness === 'codex') {
|
|
3364
|
-
const recovered =
|
|
3365
|
-
|
|
3428
|
+
const recovered = opts.codexTurnEdits
|
|
3429
|
+
? extractCompletedCodexTurnPatchEdits(envelope.transcript, root || cwd)
|
|
3430
|
+
: extractCompletedCodexPatchEdits(envelope.transcript, root || cwd);
|
|
3431
|
+
if (recovered.length) {
|
|
3432
|
+
envelope.transcriptEdits = recovered;
|
|
3433
|
+
if (opts.codexTurnEdits) {
|
|
3434
|
+
envelope.editBatch = recovered.map((item) => ({
|
|
3435
|
+
...item,
|
|
3436
|
+
payload: {
|
|
3437
|
+
...item.payload,
|
|
3438
|
+
__synkro_post_edit_enforcement: true,
|
|
3439
|
+
},
|
|
3440
|
+
}));
|
|
3441
|
+
envelope.payload = envelope.editBatch[0].payload;
|
|
3442
|
+
envelope.baseContent = envelope.editBatch[0].baseContent;
|
|
3443
|
+
}
|
|
3444
|
+
}
|
|
3366
3445
|
}
|
|
3367
3446
|
} catch {}
|
|
3368
3447
|
}
|
|
3369
3448
|
}
|
|
3449
|
+
// No completed apply_patch in this turn means there is nothing for the
|
|
3450
|
+
// fallback to scan. Stay silent and avoid touching the server/database.
|
|
3451
|
+
if (opts.codexTurnEdits && (!Array.isArray(envelope.editBatch) || envelope.editBatch.length === 0)) {
|
|
3452
|
+
out(failOpen(harness));
|
|
3453
|
+
return;
|
|
3454
|
+
}
|
|
3370
3455
|
if (opts.needsPlan) {
|
|
3371
3456
|
const ti = payload.tool_input || {};
|
|
3372
3457
|
envelope.planText = String(ti.plan || ti.content || payload.plan || '');
|
|
@@ -3421,7 +3506,10 @@ export async function runStub(surface: string, opts: StubOpts = {}): Promise<voi
|
|
|
3421
3506
|
} catch (e) { /* connection refused / timeout → retry below */ }
|
|
3422
3507
|
if (i < attempts - 1) await new Promise((r) => setTimeout(r, 500 * (i + 1)));
|
|
3423
3508
|
}
|
|
3424
|
-
const
|
|
3509
|
+
const rawResponseText = text || failOpen(harness);
|
|
3510
|
+
const responseText = opts.stopContract && harness === 'codex'
|
|
3511
|
+
? codexStopResponse(rawResponseText)
|
|
3512
|
+
: rawResponseText;
|
|
3425
3513
|
out(responseText);
|
|
3426
3514
|
emitStubTelemetry(surface, harness, telemPayload, responseText, Date.now() - startedAt, telemCwd, telemSessionId);
|
|
3427
3515
|
} catch (err) {
|
|
@@ -3668,6 +3756,8 @@ function emitStubTelemetry(
|
|
|
3668
3756
|
STUB_STOP_SUMMARY_TS = stubHook("stop-summary", "{ needsTranscript: true, fullTranscript: true }");
|
|
3669
3757
|
STUB_SESSION_START_TS = stubHook("session-start", "{ telemetry: true }");
|
|
3670
3758
|
STUB_TRANSCRIPT_SYNC_TS = stubHook("transcript-sync", "{ needsTranscript: true, fullTranscript: true, telemetry: true }");
|
|
3759
|
+
STUB_CODEX_CWE_STOP_TS = stubHook("cwe-precheck", "{ needsTranscript: true, fullTranscript: true, codexTurnEdits: true, stopContract: true }");
|
|
3760
|
+
STUB_CODEX_CVE_STOP_TS = stubHook("cve-precheck", "{ needsTranscript: true, fullTranscript: true, codexTurnEdits: true, stopContract: true }");
|
|
3671
3761
|
STUB_SUBAGENT_START_TS = stubHook("subagent-start", "{ telemetry: true, subagent: true }");
|
|
3672
3762
|
STUB_SUBAGENT_STOP_TS = stubHook("subagent-stop", "{ needsTranscript: true, fullTranscript: true, telemetry: true, subagent: true }");
|
|
3673
3763
|
STUB_USER_PROMPT_SUBMIT_TS = stubHook("prompt-submit", "{ telemetry: true }");
|
|
@@ -6695,7 +6785,7 @@ var init_dockerInstall = __esm({
|
|
|
6695
6785
|
HOST_PGLITE_PORT = parseInt(process.env.SYNKRO_HOST_PGLITE_PORT || "15433", 10);
|
|
6696
6786
|
CONTAINER_NAME = resolveContainerName();
|
|
6697
6787
|
defaultImageVersion = () => {
|
|
6698
|
-
if (true) return "1.7.
|
|
6788
|
+
if (true) return "1.7.90";
|
|
6699
6789
|
try {
|
|
6700
6790
|
const pkg = JSON.parse(readFileSync17(new URL("../../package.json", import.meta.url), "utf8"));
|
|
6701
6791
|
if (pkg.version) return pkg.version;
|
|
@@ -7625,6 +7715,8 @@ function writeHookScripts() {
|
|
|
7625
7715
|
const planJudgeScriptPath = join19(HOOKS_DIR, "cc-plan-judge.ts");
|
|
7626
7716
|
const agentJudgeScriptPath = join19(HOOKS_DIR, "cc-agent-judge.ts");
|
|
7627
7717
|
const stopSummaryScriptPath = join19(HOOKS_DIR, "cc-stop-summary.ts");
|
|
7718
|
+
const cweStopScriptPath = join19(HOOKS_DIR, "codex-cwe-stop.ts");
|
|
7719
|
+
const cveStopScriptPath = join19(HOOKS_DIR, "codex-cve-stop.ts");
|
|
7628
7720
|
const sessionStartScriptPath = join19(HOOKS_DIR, "cc-session-start.ts");
|
|
7629
7721
|
const transcriptSyncScriptPath = join19(HOOKS_DIR, "cc-transcript-sync.ts");
|
|
7630
7722
|
const subagentStartScriptPath = join19(HOOKS_DIR, "codex-subagent-start.ts");
|
|
@@ -7654,6 +7746,8 @@ function writeHookScripts() {
|
|
|
7654
7746
|
[planJudgeScriptPath, STUB_PLAN_JUDGE_TS],
|
|
7655
7747
|
[agentJudgeScriptPath, STUB_AGENT_JUDGE_TS],
|
|
7656
7748
|
[stopSummaryScriptPath, STUB_STOP_SUMMARY_TS],
|
|
7749
|
+
[cweStopScriptPath, STUB_CODEX_CWE_STOP_TS],
|
|
7750
|
+
[cveStopScriptPath, STUB_CODEX_CVE_STOP_TS],
|
|
7657
7751
|
[sessionStartScriptPath, STUB_SESSION_START_TS],
|
|
7658
7752
|
[transcriptSyncScriptPath, STUB_TRANSCRIPT_SYNC_TS],
|
|
7659
7753
|
[subagentStartScriptPath, STUB_SUBAGENT_START_TS],
|
|
@@ -7691,6 +7785,8 @@ function writeHookScripts() {
|
|
|
7691
7785
|
planJudgeScript: planJudgeScriptPath,
|
|
7692
7786
|
agentJudgeScript: agentJudgeScriptPath,
|
|
7693
7787
|
stopSummaryScript: stopSummaryScriptPath,
|
|
7788
|
+
cweStopScript: cweStopScriptPath,
|
|
7789
|
+
cveStopScript: cveStopScriptPath,
|
|
7694
7790
|
sessionStartScript: sessionStartScriptPath,
|
|
7695
7791
|
transcriptSyncScript: transcriptSyncScriptPath,
|
|
7696
7792
|
subagentStartScript: subagentStartScriptPath,
|
|
@@ -7734,7 +7830,7 @@ function writeConfigEnv(opts) {
|
|
|
7734
7830
|
`SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle2(credsPath)}`,
|
|
7735
7831
|
`SYNKRO_TIER=${shellQuoteSingle2(safeTier)}`,
|
|
7736
7832
|
`SYNKRO_INFERENCE=${shellQuoteSingle2(safeInference)}`,
|
|
7737
|
-
`SYNKRO_VERSION=${shellQuoteSingle2("1.7.
|
|
7833
|
+
`SYNKRO_VERSION=${shellQuoteSingle2("1.7.90")}`
|
|
7738
7834
|
];
|
|
7739
7835
|
if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle2(safeSynkroBin)}`);
|
|
7740
7836
|
if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle2(safeUserId)}`);
|
|
@@ -8476,7 +8572,7 @@ async function installCommand(opts = {}) {
|
|
|
8476
8572
|
await setTelemetryState({ enabled: true, remoteFlushEnabled: telemetryConsent });
|
|
8477
8573
|
emit("install", {
|
|
8478
8574
|
phase: "started",
|
|
8479
|
-
cli_version_to: "1.7.
|
|
8575
|
+
cli_version_to: "1.7.90",
|
|
8480
8576
|
agents_detected: agents.map((a) => a.kind),
|
|
8481
8577
|
with_github: false,
|
|
8482
8578
|
with_local_cc: false,
|
|
@@ -8558,6 +8654,8 @@ async function installCommand(opts = {}) {
|
|
|
8558
8654
|
cvePrecheckScriptPath: scripts.cvePrecheckScript,
|
|
8559
8655
|
agentJudgeScriptPath: scripts.agentJudgeScript,
|
|
8560
8656
|
stopSummaryScriptPath: scripts.stopSummaryScript,
|
|
8657
|
+
cweStopScriptPath: scripts.cweStopScript,
|
|
8658
|
+
cveStopScriptPath: scripts.cveStopScript,
|
|
8561
8659
|
sessionStartScriptPath: scripts.sessionStartScript,
|
|
8562
8660
|
transcriptSyncScriptPath: scripts.transcriptSyncScript,
|
|
8563
8661
|
subagentStartScriptPath: scripts.subagentStartScript,
|
|
@@ -9239,6 +9337,8 @@ function reconcileHarness() {
|
|
|
9239
9337
|
cvePrecheckScriptPath: scripts.cvePrecheckScript,
|
|
9240
9338
|
agentJudgeScriptPath: scripts.agentJudgeScript,
|
|
9241
9339
|
stopSummaryScriptPath: scripts.stopSummaryScript,
|
|
9340
|
+
cweStopScriptPath: scripts.cweStopScript,
|
|
9341
|
+
cveStopScriptPath: scripts.cveStopScript,
|
|
9242
9342
|
sessionStartScriptPath: scripts.sessionStartScript,
|
|
9243
9343
|
transcriptSyncScriptPath: scripts.transcriptSyncScript,
|
|
9244
9344
|
subagentStartScriptPath: scripts.subagentStartScript,
|
|
@@ -14511,7 +14611,7 @@ var subArgs = args.slice(1);
|
|
|
14511
14611
|
var isDetachedChild = process.env.SYNKRO_TELEMETRY_DETACHED === "1";
|
|
14512
14612
|
var FLUSH_SKIP = /* @__PURE__ */ new Set(["grade", "version", "--version", "-v", "help", "--help", "-h", ""]);
|
|
14513
14613
|
function printVersion() {
|
|
14514
|
-
console.log("1.7.
|
|
14614
|
+
console.log("1.7.90");
|
|
14515
14615
|
}
|
|
14516
14616
|
function printHelp2() {
|
|
14517
14617
|
console.log(`Synkro CLI \u2014 runtime safety for AI coding agents
|