@synkro-sh/cli 1.10.4 → 1.10.5

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
@@ -147,7 +147,7 @@ function getIdentity() {
147
147
  if (cached2) return cached2;
148
148
  let cliVersion2 = "0.0.0";
149
149
  try {
150
- cliVersion2 = "1.10.4";
150
+ cliVersion2 = "1.10.5";
151
151
  } catch {
152
152
  }
153
153
  const creds = loadCredentialsIdentity();
@@ -7840,7 +7840,7 @@ var init_dockerInstall = __esm({
7840
7840
  HOST_PGLITE_PORT = parseInt(process.env.SYNKRO_HOST_PGLITE_PORT || "15433", 10);
7841
7841
  CONTAINER_NAME = resolveContainerName();
7842
7842
  defaultImageVersion = () => {
7843
- if (true) return "1.10.4";
7843
+ if (true) return "1.10.5";
7844
7844
  try {
7845
7845
  const pkg = JSON.parse(readFileSync17(new URL("../../package.json", import.meta.url), "utf8"));
7846
7846
  if (pkg.version) return pkg.version;
@@ -8900,7 +8900,7 @@ function writeConfigEnv(opts) {
8900
8900
  `SYNKRO_CREDENTIALS_PATH=${shellQuoteSingle2(credsPath)}`,
8901
8901
  `SYNKRO_TIER=${shellQuoteSingle2(safeTier)}`,
8902
8902
  `SYNKRO_INFERENCE=${shellQuoteSingle2(safeInference)}`,
8903
- `SYNKRO_VERSION=${shellQuoteSingle2("1.10.4")}`
8903
+ `SYNKRO_VERSION=${shellQuoteSingle2("1.10.5")}`
8904
8904
  ];
8905
8905
  if (safeSynkroBin) lines.push(`SYNKRO_CLI_BIN=${shellQuoteSingle2(safeSynkroBin)}`);
8906
8906
  if (safeUserId) lines.push(`SYNKRO_USER_ID=${shellQuoteSingle2(safeUserId)}`);
@@ -9647,7 +9647,7 @@ async function installCommand(opts = {}) {
9647
9647
  await setTelemetryState({ enabled: true, remoteFlushEnabled: telemetryConsent });
9648
9648
  emit("install", {
9649
9649
  phase: "started",
9650
- cli_version_to: "1.10.4",
9650
+ cli_version_to: "1.10.5",
9651
9651
  agents_detected: agents.map((a) => a.kind),
9652
9652
  with_github: false,
9653
9653
  with_local_cc: false,
@@ -16705,11 +16705,14 @@ var init_events = __esm({
16705
16705
  });
16706
16706
 
16707
16707
  // cli/harness/cursor.ts
16708
+ function unwrapReplay(text) {
16709
+ return text.replace(/<\/?user_query>/gi, "").trim();
16710
+ }
16708
16711
  function textOf(message) {
16709
16712
  const content = message?.content;
16710
- if (typeof content === "string") return content.trim();
16713
+ if (typeof content === "string") return unwrapReplay(content);
16711
16714
  if (!Array.isArray(content)) return "";
16712
- return content.filter((part) => part && (part.type === "text" || typeof part.text === "string")).map((part) => String(part.text || "")).join("").trim();
16715
+ return unwrapReplay(content.filter((part) => part && (part.type === "text" || typeof part.text === "string")).map((part) => String(part.text || "")).join(""));
16713
16716
  }
16714
16717
  function toolPayload(toolCall) {
16715
16718
  if (!toolCall) return { kind: "other", body: {} };
@@ -16784,6 +16787,15 @@ function parseCursorLine(line) {
16784
16787
  }
16785
16788
  return [];
16786
16789
  }
16790
+ if (type === "retry") {
16791
+ if (subtype !== "starting") return [];
16792
+ const attempt = Number(frame.attempt || 0);
16793
+ return [{
16794
+ type: "notice",
16795
+ kind: "retry",
16796
+ text: "connection dropped, resuming" + (attempt ? " (attempt " + attempt + ")" : "") + "\u2026"
16797
+ }];
16798
+ }
16787
16799
  if (type === "result") {
16788
16800
  return [{
16789
16801
  type: "turn-end",
@@ -16924,49 +16936,94 @@ var init_render2 = __esm({
16924
16936
 
16925
16937
  // cli/harness/run.ts
16926
16938
  import { spawn as spawn9 } from "child_process";
16927
- async function runCursorTurn(opts) {
16928
- const write2 = opts.write || ((text) => process.stdout.write(text));
16929
- const width = opts.width || Number(process.stdout.columns || 100);
16939
+ function replayKey(event) {
16940
+ switch (event.type) {
16941
+ case "user-message":
16942
+ return "u:" + event.text;
16943
+ case "assistant-message":
16944
+ return "a:" + event.text;
16945
+ case "tool-start":
16946
+ return "s:" + event.id;
16947
+ case "tool-end":
16948
+ return "e:" + event.id;
16949
+ default:
16950
+ return "";
16951
+ }
16952
+ }
16953
+ function createTurnSink(opts) {
16930
16954
  const events = [];
16931
16955
  let blocked = 0;
16932
16956
  let lastWasThinking = false;
16957
+ let replaying = false;
16958
+ const seen = /* @__PURE__ */ new Set();
16959
+ let sawTurnEnd = false;
16960
+ let sawAnswer = false;
16961
+ let buffer = "";
16962
+ const emit2 = (event) => {
16963
+ events.push(event);
16964
+ if (event.type === "tool-end" && event.blocked) blocked += 1;
16965
+ opts.onEvent?.(event);
16966
+ if (event.type === "thinking") {
16967
+ if (lastWasThinking) return;
16968
+ lastWasThinking = true;
16969
+ } else {
16970
+ lastWasThinking = false;
16971
+ }
16972
+ const rendered = renderEvent(event, opts.width);
16973
+ if (rendered.length) opts.write(rendered.join("\n") + "\n");
16974
+ };
16975
+ const take = (event) => {
16976
+ if (event.type === "notice" && event.kind === "retry") replaying = true;
16977
+ const key = replayKey(event);
16978
+ if (key) {
16979
+ if (replaying && seen.has(key)) return;
16980
+ seen.add(key);
16981
+ }
16982
+ if (event.type === "turn-end") sawTurnEnd = true;
16983
+ if (event.type === "assistant-message") sawAnswer = true;
16984
+ emit2(event);
16985
+ };
16986
+ return {
16987
+ chunk(text) {
16988
+ const { lines, rest } = feed(buffer, text);
16989
+ buffer = rest;
16990
+ for (const line of lines) for (const event of parseCursorLine(line)) take(event);
16991
+ },
16992
+ notice(text) {
16993
+ emit2({ type: "notice", text });
16994
+ },
16995
+ finish(exit) {
16996
+ if (!sawTurnEnd) {
16997
+ if (exit !== 0) {
16998
+ emit2({
16999
+ type: "notice",
17000
+ text: sawAnswer ? "cursor-agent exited " + exit + " after retrying; the reply above is complete" : "cursor-agent exited " + exit + " without completing the turn"
17001
+ });
17002
+ }
17003
+ emit2({ type: "turn-end", ok: sawAnswer, text: "" });
17004
+ }
17005
+ return { events, blocked, exitCode: sawAnswer ? 0 : exit };
17006
+ }
17007
+ };
17008
+ }
17009
+ async function runCursorTurn(opts) {
17010
+ const write2 = opts.write || ((text) => process.stdout.write(text));
17011
+ const width = opts.width || Number(process.stdout.columns || 100);
17012
+ const sink = createTurnSink({ write: write2, onEvent: opts.onEvent, width });
16933
17013
  return new Promise((resolve7) => {
16934
17014
  const child = spawn9("cursor-agent", cursorArgs(opts.prompt), {
16935
17015
  cwd: opts.cwd,
16936
17016
  stdio: ["ignore", "pipe", "pipe"]
16937
17017
  });
16938
- let buffer = "";
16939
- child.stdout.on("data", (chunk) => {
16940
- const { lines, rest } = feed(buffer, chunk.toString("utf8"));
16941
- buffer = rest;
16942
- for (const line of lines) {
16943
- for (const event of parseCursorLine(line)) {
16944
- events.push(event);
16945
- if (event.type === "tool-end" && event.blocked) blocked += 1;
16946
- opts.onEvent?.(event);
16947
- if (event.type === "thinking") {
16948
- if (lastWasThinking) continue;
16949
- lastWasThinking = true;
16950
- } else {
16951
- lastWasThinking = false;
16952
- }
16953
- const rendered = renderEvent(event, width);
16954
- if (rendered.length) write2(rendered.join("\n") + "\n");
16955
- }
16956
- }
16957
- });
17018
+ child.stdout.on("data", (chunk) => sink.chunk(chunk.toString("utf8")));
16958
17019
  child.stderr.on("data", (chunk) => {
16959
17020
  const text = chunk.toString("utf8").trim();
16960
- if (/error|fatal/i.test(text) && !/RetriableError/i.test(text)) {
16961
- write2(renderEvent({ type: "notice", text }, width).join("\n") + "\n");
16962
- }
16963
- });
16964
- child.on("close", (code) => {
16965
- resolve7({ events, blocked, exitCode: code ?? 0 });
17021
+ if (/error|fatal/i.test(text) && !/RetriableError/i.test(text)) sink.notice(text);
16966
17022
  });
17023
+ child.on("close", (code) => resolve7(sink.finish(code ?? 0)));
16967
17024
  child.on("error", (error) => {
16968
- write2(renderEvent({ type: "notice", text: "failed to start cursor-agent: " + String(error) }, width).join("\n") + "\n");
16969
- resolve7({ events, blocked, exitCode: 1 });
17025
+ sink.notice("failed to start cursor-agent: " + String(error));
17026
+ resolve7(sink.finish(1));
16970
17027
  });
16971
17028
  });
16972
17029
  }
@@ -18312,7 +18369,7 @@ function pseudonymousHostnameHash(installationId, host) {
18312
18369
  }
18313
18370
  function cliVersion() {
18314
18371
  try {
18315
- return "1.10.4";
18372
+ return "1.10.5";
18316
18373
  } catch {
18317
18374
  return "0.0.0";
18318
18375
  }
@@ -19082,7 +19139,7 @@ var subArgs = args.slice(1);
19082
19139
  var isDetachedChild = process.env.SYNKRO_TELEMETRY_DETACHED === "1";
19083
19140
  var FLUSH_SKIP = /* @__PURE__ */ new Set(["grade", "inventory-sync", "version", "--version", "-v", "help", "--help", "-h", ""]);
19084
19141
  function printVersion() {
19085
- console.log("1.10.4");
19142
+ console.log("1.10.5");
19086
19143
  }
19087
19144
  function printHelp2() {
19088
19145
  console.log(`Synkro CLI \u2014 runtime safety for AI coding agents