@synkro-sh/cli 1.6.86 → 1.6.87
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 +71 -11
- package/dist/bootstrap.js.map +1 -1
- package/package.json +1 -1
package/dist/bootstrap.js
CHANGED
|
@@ -2173,8 +2173,68 @@ export function readSessionLog(sessionId: string): SessionAction[] {
|
|
|
2173
2173
|
} catch { return []; }
|
|
2174
2174
|
}
|
|
2175
2175
|
|
|
2176
|
-
|
|
2176
|
+
const RETRIEVAL_RECENT_N = 40;
|
|
2177
|
+
const PROCESS_KW = ['test', 'typecheck', 'tsc', 'lint', 'build', 'migrate', 'migration', 'deploy', 'publish', 'push', 'seed'];
|
|
2178
|
+
|
|
2179
|
+
// Is this session action security- or rule-relevant (i.e. can it participate in a
|
|
2180
|
+
// violation)? Conservative net \u2014 uses substring checks (no regex, to stay safe
|
|
2181
|
+
// inside the materialized-hook template). Plus rule-awareness: an action that
|
|
2182
|
+
// performs a process keyword an active rule actually mentions (e.g. a "pnpm test"
|
|
2183
|
+
// when a rule is about tests) is kept so precondition rules stay resolvable.
|
|
2184
|
+
function actionSalience(a: SessionAction, ruleText: string): string | null {
|
|
2185
|
+
const x = ((a.tool || '') + ' ' + (a.file || '') + ' ' + (a.summary || '')).toLowerCase();
|
|
2186
|
+
const has = (arr: string[]): boolean => { for (const k of arr) if (x.indexOf(k) >= 0) return true; return false; };
|
|
2187
|
+
if (has(['.env', 'credential', 'secret', 'token', '.pem', '.key', 'password', 'api key', 'api_key', 'api-key', 'authorization', 'bearer', 'oauth', '.aws'])) return 'secret';
|
|
2188
|
+
if (has(['curl ', 'wget ', 'ssh ', 'scp ', 'netcat', 'http://', 'https://', 'fetch('])) return 'network';
|
|
2189
|
+
if (has(['rm -rf', 'rm -r ', 'drop table', 'drop database', 'truncate', 'chmod', 'chown', 'sudo', 'kill ', 'wrangler', '--force', 'deploy', 'publish', 'git push'])) return 'destructive';
|
|
2190
|
+
for (const kw of PROCESS_KW) if (ruleText.indexOf(kw) >= 0 && x.indexOf(kw) >= 0) return 'rule';
|
|
2191
|
+
return null;
|
|
2192
|
+
}
|
|
2193
|
+
|
|
2194
|
+
// Cloud session log \u2014 retrieval style (validated 4/4 vs the last-200 dump in the
|
|
2195
|
+
// shadow corpus). Keeps EVERY security-salient + rule-relevant action in order
|
|
2196
|
+
// regardless of age (so cross-turn violations the dump's 200-window drops are
|
|
2197
|
+
// still seen), a recent verbatim window, and a COMPLETENESS-asserting summary of
|
|
2198
|
+
// the routine remainder (the assertion is what lets the grader trust the collapsed
|
|
2199
|
+
// part is benign \u2014 safe only because the salience net above is conservative).
|
|
2200
|
+
function compressSessionLogRetrieval(actions: SessionAction[], rules: Rule[]): string {
|
|
2201
|
+
if (actions.length === 0) return '';
|
|
2202
|
+
const ruleText = (rules || []).map(r => String((r as any).text || '').toLowerCase()).join(' ');
|
|
2203
|
+
const total = actions.length;
|
|
2204
|
+
const recentStart = Math.max(0, total - RETRIEVAL_RECENT_N);
|
|
2205
|
+
const salient: Array<{ a: SessionAction; s: string; i: number }> = [];
|
|
2206
|
+
const noise: Record<string, number> = {};
|
|
2207
|
+
for (let i = 0; i < recentStart; i++) {
|
|
2208
|
+
const a = actions[i];
|
|
2209
|
+
const s = actionSalience(a, ruleText);
|
|
2210
|
+
if (s) salient.push({ a, s, i });
|
|
2211
|
+
else noise[a.tool] = (noise[a.tool] || 0) + 1;
|
|
2212
|
+
}
|
|
2213
|
+
const lines: string[] = ['SESSION HISTORY (' + total + ' actions; security-salient + recent, in order):'];
|
|
2214
|
+
if (salient.length) {
|
|
2215
|
+
lines.push(' --- relevant (any point this session) ---');
|
|
2216
|
+
for (const r of salient) {
|
|
2217
|
+
const target = r.a.file || (r.a.summary || '').slice(0, 80);
|
|
2218
|
+
lines.push(' ' + (r.i + 1) + '. [' + r.s + '] ' + r.a.tool + ' ' + target + (r.a.outcome ? ' -> ' + r.a.outcome : ''));
|
|
2219
|
+
}
|
|
2220
|
+
}
|
|
2221
|
+
const noiseN = Object.values(noise).reduce((n, c) => n + c, 0);
|
|
2222
|
+
if (noiseN) {
|
|
2223
|
+
lines.push(' [' + noiseN + ' earlier routine actions (' + Object.entries(noise).map(([t, c]) => c + ' ' + t).join(', ') + '). The relevant list above is COMPLETE: every credential/secret read, outbound network call, and destructive or rule-gated action this session is listed there; these ' + noiseN + ' are non-salient in-repo reads/edits/builds only.]');
|
|
2224
|
+
}
|
|
2225
|
+
lines.push(' --- recent ---');
|
|
2226
|
+
for (let i = recentStart; i < total; i++) {
|
|
2227
|
+
const a = actions[i];
|
|
2228
|
+
lines.push(' ' + (i + 1) + '. ' + (a.summary || a.tool) + (a.outcome ? ' -> ' + a.outcome : ''));
|
|
2229
|
+
}
|
|
2230
|
+
return lines.join('\\n');
|
|
2231
|
+
}
|
|
2232
|
+
|
|
2233
|
+
export function compressSessionLog(actions: SessionAction[], rules?: Rule[]): string {
|
|
2177
2234
|
if (actions.length === 0) return '';
|
|
2235
|
+
// Cloud grade path passes the active rules \u2192 retrieval-style context. Local
|
|
2236
|
+
// (no rules arg, or local storage mode) keeps the dump below, UNTOUCHED.
|
|
2237
|
+
if (rules !== undefined && !isLocalStorageMode()) return compressSessionLogRetrieval(actions, rules);
|
|
2178
2238
|
const total = actions.length;
|
|
2179
2239
|
const lines: string[] = [];
|
|
2180
2240
|
|
|
@@ -4088,7 +4148,7 @@ async function main() {
|
|
|
4088
4148
|
if (rt === 'local') {
|
|
4089
4149
|
// \u2500\u2500\u2500 Local grading: org rules ONLY (channel 1, port 18929) \u2500\u2500\u2500
|
|
4090
4150
|
const proposedShort = proposed.slice(0, 4000);
|
|
4091
|
-
const sessionLog = compressSessionLog(readSessionLog(sessionId));
|
|
4151
|
+
const sessionLog = compressSessionLog(readSessionLog(sessionId), config.rules);
|
|
4092
4152
|
const graderContent = 'file=' + filePath + ' content=' + proposedShort;
|
|
4093
4153
|
const relevantRules = await filterRules(
|
|
4094
4154
|
ruleFilterText(graderContent, transcript.userIntent || lastPrompt),
|
|
@@ -4281,7 +4341,7 @@ async function main() {
|
|
|
4281
4341
|
recent_user_messages: transcript.recentUserMessages,
|
|
4282
4342
|
recent_messages: transcript.recentMessages,
|
|
4283
4343
|
recent_actions: transcript.recentActions,
|
|
4284
|
-
session_history: compressSessionLog(readSessionLog(sessionId)),
|
|
4344
|
+
session_history: compressSessionLog(readSessionLog(sessionId), config.rules),
|
|
4285
4345
|
session_id: sessionId || null,
|
|
4286
4346
|
tool_use_id: toolUseId || null,
|
|
4287
4347
|
cwd: cwd || null,
|
|
@@ -5520,7 +5580,7 @@ async function main() {
|
|
|
5520
5580
|
// mode was also checked up there.
|
|
5521
5581
|
|
|
5522
5582
|
if (rt === 'local') {
|
|
5523
|
-
const sessionLog = compressSessionLog(readSessionLog(sessionId));
|
|
5583
|
+
const sessionLog = compressSessionLog(readSessionLog(sessionId), config.rules);
|
|
5524
5584
|
const relevantRules = await filterRules(
|
|
5525
5585
|
ruleFilterText(command, transcript.userIntent || lastPrompt),
|
|
5526
5586
|
config.rules,
|
|
@@ -5602,7 +5662,7 @@ async function main() {
|
|
|
5602
5662
|
recent_user_messages: transcript.recentUserMessages,
|
|
5603
5663
|
recent_messages: transcript.recentMessages,
|
|
5604
5664
|
recent_actions: transcript.recentActions,
|
|
5605
|
-
session_history: compressSessionLog(readSessionLog(sessionId)),
|
|
5665
|
+
session_history: compressSessionLog(readSessionLog(sessionId), config.rules),
|
|
5606
5666
|
session_id: sessionId || null,
|
|
5607
5667
|
tool_use_id: toolUseId || null,
|
|
5608
5668
|
cwd: cwd || null,
|
|
@@ -5735,7 +5795,7 @@ async function main() {
|
|
|
5735
5795
|
}
|
|
5736
5796
|
|
|
5737
5797
|
if (rt === 'local') {
|
|
5738
|
-
const sessionLog = compressSessionLog(readSessionLog(sessionId));
|
|
5798
|
+
const sessionLog = compressSessionLog(readSessionLog(sessionId), config.rules);
|
|
5739
5799
|
const agentText = 'agent=' + subagentType + ' description=' + description + ' prompt=' + prompt.slice(0, 2000);
|
|
5740
5800
|
const relevantRules = await filterRules(agentText, config.rules);
|
|
5741
5801
|
const graderPrompt = [
|
|
@@ -5808,7 +5868,7 @@ async function main() {
|
|
|
5808
5868
|
recent_user_messages: transcript.recentUserMessages,
|
|
5809
5869
|
recent_messages: transcript.recentMessages,
|
|
5810
5870
|
recent_actions: transcript.recentActions,
|
|
5811
|
-
session_history: compressSessionLog(readSessionLog(sessionId)),
|
|
5871
|
+
session_history: compressSessionLog(readSessionLog(sessionId), config.rules),
|
|
5812
5872
|
session_id: sessionId || null,
|
|
5813
5873
|
tool_use_id: toolUseId || null,
|
|
5814
5874
|
cwd: cwd || null,
|
|
@@ -5953,7 +6013,7 @@ async function main() {
|
|
|
5953
6013
|
}
|
|
5954
6014
|
|
|
5955
6015
|
if (rt === 'local') {
|
|
5956
|
-
const sessionLog = compressSessionLog(readSessionLog(sessionId));
|
|
6016
|
+
const sessionLog = compressSessionLog(readSessionLog(sessionId), config.rules);
|
|
5957
6017
|
const relevantRules = await filterRules(plan.slice(0, 2000), config.rules);
|
|
5958
6018
|
const graderPrompt = [
|
|
5959
6019
|
'Working directory: ' + (cwd || '.'),
|
|
@@ -6559,7 +6619,7 @@ async function main() {
|
|
|
6559
6619
|
}
|
|
6560
6620
|
|
|
6561
6621
|
if (rt === 'local') {
|
|
6562
|
-
const sessionLog = compressSessionLog(readSessionLog(sessionId));
|
|
6622
|
+
const sessionLog = compressSessionLog(readSessionLog(sessionId), config.rules);
|
|
6563
6623
|
const relevantRules = await filterRules(
|
|
6564
6624
|
ruleFilterText(command, transcript.userIntent || lastPrompt),
|
|
6565
6625
|
config.rules,
|
|
@@ -10856,7 +10916,7 @@ function writeConfigEnv(opts) {
|
|
|
10856
10916
|
`SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
|
|
10857
10917
|
`SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
|
|
10858
10918
|
`SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
|
|
10859
|
-
`SYNKRO_VERSION=${shellQuoteSingle("1.6.
|
|
10919
|
+
`SYNKRO_VERSION=${shellQuoteSingle("1.6.87")}`
|
|
10860
10920
|
];
|
|
10861
10921
|
if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle(safeSynkroBin)}`);
|
|
10862
10922
|
if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
|
|
@@ -14899,7 +14959,7 @@ var args = process.argv.slice(2);
|
|
|
14899
14959
|
var cmd = args[0] || "";
|
|
14900
14960
|
var subArgs = args.slice(1);
|
|
14901
14961
|
function printVersion() {
|
|
14902
|
-
console.log("1.6.
|
|
14962
|
+
console.log("1.6.87");
|
|
14903
14963
|
}
|
|
14904
14964
|
function printHelp2() {
|
|
14905
14965
|
console.log(`Synkro CLI \u2014 runtime safety for AI coding agents
|