@synkro-sh/cli 1.6.81 → 1.6.82

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
@@ -2989,35 +2989,38 @@ export async function syncConversationTranscript(
2989
2989
  const entry = JSON.parse(allLines[i]) as Record<string, unknown>;
2990
2990
  const kind = transcriptEntryType(entry);
2991
2991
  if (kind !== 'user' && kind !== 'assistant') continue;
2992
- const text = extractTranscriptEntryText(entry, 8000, sessionId);
2993
- if (!text) continue;
2994
-
2995
2992
  const msgObj = entry.message as Record<string, unknown> | undefined;
2996
2993
  const content = (msgObj && typeof msgObj === 'object' ? msgObj.content : undefined) ?? entry.content;
2997
2994
  const singleBlock = transcriptContentBlock(entry);
2995
+ // Tool calls FIRST \u2014 a tool-only assistant turn (Edit/Bash/Read, no text) is
2996
+ // most of a coding session and must still be captured; skipping on empty text
2997
+ // dropped both the turn and its tool calls.
2998
+ const blocks = (kind === 'assistant')
2999
+ ? (Array.isArray(content) ? content : (singleBlock ? [singleBlock] : []))
3000
+ : [];
3001
+ const toolCalls = blocks
3002
+ .filter((c: unknown) => {
3003
+ const b = c as Record<string, unknown>;
3004
+ return b?.type === 'tool_use' || b?.type === 'tool_call';
3005
+ })
3006
+ .map((c: unknown) => {
3007
+ const b = c as Record<string, unknown>;
3008
+ return {
3009
+ name: b.name,
3010
+ input: JSON.stringify(b.input || b.arguments || {}).slice(0, 500),
3011
+ id: b.id,
3012
+ };
3013
+ });
3014
+ const text = extractTranscriptEntryText(entry, 8000, sessionId);
3015
+ if (!text && toolCalls.length === 0) continue;
3016
+
2998
3017
  const msg: Record<string, unknown> = {
2999
3018
  message_index: i,
3000
3019
  type: kind,
3001
- content: text,
3020
+ content: text || ('\u21B3 ' + toolCalls.map((t: any) => t.name).join(', ')),
3002
3021
  ts: entry.timestamp || null,
3003
3022
  };
3004
3023
  if (kind === 'assistant') {
3005
- const blocks = Array.isArray(content)
3006
- ? content
3007
- : (singleBlock ? [singleBlock] : []);
3008
- const toolCalls = blocks
3009
- .filter((c: unknown) => {
3010
- const b = c as Record<string, unknown>;
3011
- return b?.type === 'tool_use' || b?.type === 'tool_call';
3012
- })
3013
- .map((c: unknown) => {
3014
- const b = c as Record<string, unknown>;
3015
- return {
3016
- name: b.name,
3017
- input: JSON.stringify(b.input || b.arguments || {}).slice(0, 500),
3018
- id: b.id,
3019
- };
3020
- });
3021
3024
  if (toolCalls.length > 0) msg.tool_calls = toolCalls;
3022
3025
  // Per-turn usage + model so the session view can show input/output/cache
3023
3026
  // tokens and cost line-by-line (not just the session aggregate).
@@ -10750,7 +10753,7 @@ function writeConfigEnv(opts) {
10750
10753
  `SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle(credsPath)}`,
10751
10754
  `SYNKRO_TIER=${shellQuoteSingle(safeTier)}`,
10752
10755
  `SYNKRO_INFERENCE=${shellQuoteSingle(safeInference)}`,
10753
- `SYNKRO_VERSION=${shellQuoteSingle("1.6.81")}`
10756
+ `SYNKRO_VERSION=${shellQuoteSingle("1.6.82")}`
10754
10757
  ];
10755
10758
  if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle(safeSynkroBin)}`);
10756
10759
  if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle(safeUserId)}`);
@@ -14169,11 +14172,17 @@ function readConfigEnv() {
14169
14172
  return out;
14170
14173
  }
14171
14174
  function projectsFolder() {
14172
- const sanitized = "-" + process.cwd().replace(/\//g, "-");
14175
+ const sanitized = process.cwd().replace(/\//g, "-");
14173
14176
  const dir = join17(homedir17(), ".claude", "projects", sanitized);
14174
14177
  return existsSync17(dir) ? dir : null;
14175
14178
  }
14176
14179
  function repoName() {
14180
+ try {
14181
+ const url = execSync7("git config --get remote.origin.url", { encoding: "utf-8" }).trim();
14182
+ const m = url.match(/[:/]([^/:]+\/[^/]+?)(?:\.git)?$/);
14183
+ if (m) return m[1];
14184
+ } catch {
14185
+ }
14177
14186
  try {
14178
14187
  return execSync7("git rev-parse --show-toplevel", { encoding: "utf-8" }).trim().split("/").pop() || "repo";
14179
14188
  } catch {
@@ -14203,11 +14212,13 @@ function parseSession(filePath, sessionId) {
14203
14212
  if (!kind) continue;
14204
14213
  const msgObj = e.message;
14205
14214
  const text = extractText(msgObj?.content ?? e.content);
14206
- if (!text.trim()) continue;
14215
+ const blocks = kind === "assistant" && Array.isArray(msgObj?.content) ? msgObj.content : [];
14216
+ const toolCalls = blocks.filter((b) => b?.type === "tool_use").map((b) => ({ name: b.name, input: JSON.stringify(b.input || {}).slice(0, 500), id: b.id }));
14217
+ if (!text.trim() && toolCalls.length === 0) continue;
14207
14218
  const msg = {
14208
14219
  message_index: i,
14209
14220
  type: kind,
14210
- content: text.slice(0, 8e3),
14221
+ content: text.trim() ? text.slice(0, 8e3) : "\u21B3 " + toolCalls.map((t) => t.name).join(", "),
14211
14222
  timestamp: e.timestamp || null
14212
14223
  };
14213
14224
  if (kind === "assistant") {
@@ -14221,8 +14232,6 @@ function parseSession(filePath, sessionId) {
14221
14232
  cache_read_input_tokens: Number(u.cache_read_input_tokens) || 0
14222
14233
  };
14223
14234
  }
14224
- const blocks = Array.isArray(msgObj?.content) ? msgObj.content : [];
14225
- const toolCalls = blocks.filter((b) => b?.type === "tool_use").map((b) => ({ name: b.name, input: JSON.stringify(b.input || {}).slice(0, 500), id: b.id }));
14226
14235
  if (toolCalls.length) {
14227
14236
  msg.tool_calls = toolCalls;
14228
14237
  for (const t of toolCalls) actions.push({ step: ++step, tool: t.name, summary: "", file: null, outcome: null });
@@ -14272,25 +14281,29 @@ async function importCommand() {
14272
14281
  return;
14273
14282
  }
14274
14283
  const gateway = config.SYNKRO_GATEWAY_URL || "https://api.synkro.sh";
14275
- for (let i = 0; i < sessions.length; i += 20) {
14276
- const batch = sessions.slice(i, i + 20);
14284
+ for (const s of sessions) {
14277
14285
  try {
14278
14286
  const r = await fetch(`${gateway}/api/v1/cli/sync-transcripts`, {
14279
14287
  method: "POST",
14280
14288
  headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
14281
- body: JSON.stringify({ repo, sessions: batch }),
14282
- signal: AbortSignal.timeout(3e4)
14289
+ body: JSON.stringify({ repo, sessions: [s] }),
14290
+ signal: AbortSignal.timeout(6e4)
14283
14291
  });
14284
- if (r.ok) ok += batch.length;
14285
- else {
14286
- fail += batch.length;
14287
- console.warn(` batch failed: HTTP ${r.status}`);
14292
+ if (r.ok) {
14293
+ ok++;
14294
+ process.stdout.write(".");
14295
+ } else {
14296
+ fail++;
14297
+ console.warn(`
14298
+ ${String(s.cc_session_id).slice(0, 8)} failed: HTTP ${r.status}`);
14288
14299
  }
14289
14300
  } catch (e) {
14290
- fail += batch.length;
14291
- console.warn(` batch error: ${e.message}`);
14301
+ fail++;
14302
+ console.warn(`
14303
+ ${String(s.cc_session_id).slice(0, 8)} error: ${e.message}`);
14292
14304
  }
14293
14305
  }
14306
+ process.stdout.write("\n");
14294
14307
  } else {
14295
14308
  const port = config.SYNKRO_MCP_PORT || "18931";
14296
14309
  for (const s of sessions) {
@@ -14601,7 +14614,7 @@ var args = process.argv.slice(2);
14601
14614
  var cmd = args[0] || "";
14602
14615
  var subArgs = args.slice(1);
14603
14616
  function printVersion() {
14604
- console.log("1.6.81");
14617
+ console.log("1.6.82");
14605
14618
  }
14606
14619
  function printHelp2() {
14607
14620
  console.log(`Synkro CLI \u2014 runtime safety for AI coding agents