replicas-cli 0.3.49 → 0.3.51

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.
Files changed (2) hide show
  1. package/dist/index.cjs +129 -101
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -999,14 +999,14 @@ var require_foldFlowLines = __commonJS({
999
999
  var FOLD_FLOW = "flow";
1000
1000
  var FOLD_BLOCK = "block";
1001
1001
  var FOLD_QUOTED = "quoted";
1002
- function foldFlowLines(text2, indent, mode = "flow", { indentAtStart, lineWidth = 80, minContentWidth = 20, onFold, onOverflow } = {}) {
1002
+ function foldFlowLines(text3, indent, mode = "flow", { indentAtStart, lineWidth = 80, minContentWidth = 20, onFold, onOverflow } = {}) {
1003
1003
  if (!lineWidth || lineWidth < 0)
1004
- return text2;
1004
+ return text3;
1005
1005
  if (lineWidth < minContentWidth)
1006
1006
  minContentWidth = 0;
1007
1007
  const endStep = Math.max(1 + minContentWidth, 1 + lineWidth - indent.length);
1008
- if (text2.length <= endStep)
1009
- return text2;
1008
+ if (text3.length <= endStep)
1009
+ return text3;
1010
1010
  const folds = [];
1011
1011
  const escapedFolds = {};
1012
1012
  let end = lineWidth - indent.length;
@@ -1023,14 +1023,14 @@ var require_foldFlowLines = __commonJS({
1023
1023
  let escStart = -1;
1024
1024
  let escEnd = -1;
1025
1025
  if (mode === FOLD_BLOCK) {
1026
- i = consumeMoreIndentedLines(text2, i, indent.length);
1026
+ i = consumeMoreIndentedLines(text3, i, indent.length);
1027
1027
  if (i !== -1)
1028
1028
  end = i + endStep;
1029
1029
  }
1030
- for (let ch; ch = text2[i += 1]; ) {
1030
+ for (let ch; ch = text3[i += 1]; ) {
1031
1031
  if (mode === FOLD_QUOTED && ch === "\\") {
1032
1032
  escStart = i;
1033
- switch (text2[i + 1]) {
1033
+ switch (text3[i + 1]) {
1034
1034
  case "x":
1035
1035
  i += 3;
1036
1036
  break;
@@ -1047,12 +1047,12 @@ var require_foldFlowLines = __commonJS({
1047
1047
  }
1048
1048
  if (ch === "\n") {
1049
1049
  if (mode === FOLD_BLOCK)
1050
- i = consumeMoreIndentedLines(text2, i, indent.length);
1050
+ i = consumeMoreIndentedLines(text3, i, indent.length);
1051
1051
  end = i + indent.length + endStep;
1052
1052
  split = void 0;
1053
1053
  } else {
1054
1054
  if (ch === " " && prev && prev !== " " && prev !== "\n" && prev !== " ") {
1055
- const next = text2[i + 1];
1055
+ const next = text3[i + 1];
1056
1056
  if (next && next !== " " && next !== "\n" && next !== " ")
1057
1057
  split = i;
1058
1058
  }
@@ -1064,12 +1064,12 @@ var require_foldFlowLines = __commonJS({
1064
1064
  } else if (mode === FOLD_QUOTED) {
1065
1065
  while (prev === " " || prev === " ") {
1066
1066
  prev = ch;
1067
- ch = text2[i += 1];
1067
+ ch = text3[i += 1];
1068
1068
  overflow = true;
1069
1069
  }
1070
1070
  const j = i > escEnd + 1 ? i - 2 : escStart - 1;
1071
1071
  if (escapedFolds[j])
1072
- return text2;
1072
+ return text3;
1073
1073
  folds.push(j);
1074
1074
  escapedFolds[j] = true;
1075
1075
  end = j + endStep;
@@ -1084,39 +1084,39 @@ var require_foldFlowLines = __commonJS({
1084
1084
  if (overflow && onOverflow)
1085
1085
  onOverflow();
1086
1086
  if (folds.length === 0)
1087
- return text2;
1087
+ return text3;
1088
1088
  if (onFold)
1089
1089
  onFold();
1090
- let res = text2.slice(0, folds[0]);
1090
+ let res = text3.slice(0, folds[0]);
1091
1091
  for (let i2 = 0; i2 < folds.length; ++i2) {
1092
1092
  const fold = folds[i2];
1093
- const end2 = folds[i2 + 1] || text2.length;
1093
+ const end2 = folds[i2 + 1] || text3.length;
1094
1094
  if (fold === 0)
1095
1095
  res = `
1096
- ${indent}${text2.slice(0, end2)}`;
1096
+ ${indent}${text3.slice(0, end2)}`;
1097
1097
  else {
1098
1098
  if (mode === FOLD_QUOTED && escapedFolds[fold])
1099
- res += `${text2[fold]}\\`;
1099
+ res += `${text3[fold]}\\`;
1100
1100
  res += `
1101
- ${indent}${text2.slice(fold + 1, end2)}`;
1101
+ ${indent}${text3.slice(fold + 1, end2)}`;
1102
1102
  }
1103
1103
  }
1104
1104
  return res;
1105
1105
  }
1106
- function consumeMoreIndentedLines(text2, i, indent) {
1106
+ function consumeMoreIndentedLines(text3, i, indent) {
1107
1107
  let end = i;
1108
1108
  let start = i + 1;
1109
- let ch = text2[start];
1109
+ let ch = text3[start];
1110
1110
  while (ch === " " || ch === " ") {
1111
1111
  if (i < start + indent) {
1112
- ch = text2[++i];
1112
+ ch = text3[++i];
1113
1113
  } else {
1114
1114
  do {
1115
- ch = text2[++i];
1115
+ ch = text3[++i];
1116
1116
  } while (ch && ch !== "\n");
1117
1117
  end = i;
1118
1118
  start = i + 1;
1119
- ch = text2[start];
1119
+ ch = text3[start];
1120
1120
  }
1121
1121
  }
1122
1122
  return end;
@@ -7380,6 +7380,7 @@ var WEB_APP_PATHS = {
7380
7380
  automations: "/automations",
7381
7381
  environment: "/environment",
7382
7382
  analytics: "/analytics",
7383
+ review: "/review",
7383
7384
  dashboard: DASHBOARD_PATH,
7384
7385
  agents: `${DASHBOARD_PATH}/agents`,
7385
7386
  integrations: `${DASHBOARD_PATH}/integrations`,
@@ -15448,8 +15449,8 @@ function ko_default() {
15448
15449
  }
15449
15450
 
15450
15451
  // ../node_modules/.bun/zod@4.4.3/node_modules/zod/v4/locales/lt.js
15451
- var capitalizeFirstCharacter = (text2) => {
15452
- return text2.charAt(0).toUpperCase() + text2.slice(1);
15452
+ var capitalizeFirstCharacter = (text3) => {
15453
+ return text3.charAt(0).toUpperCase() + text3.slice(1);
15453
15454
  };
15454
15455
  function getUnitTypeFromNumber(number4) {
15455
15456
  const abs = Math.abs(number4);
@@ -22346,7 +22347,6 @@ function isWorkspaceSize(value) {
22346
22347
  var INVALID_WORKSPACE_SIZE_ERROR = `Invalid size: must be one of ${WORKSPACE_SIZES.join(", ")}`;
22347
22348
 
22348
22349
  // ../shared/src/pricing.ts
22349
- var TRIAL_DURATION_DAYS = 14;
22350
22350
  var TRIAL_CREDIT_CENTS = 1e4;
22351
22351
  var WORKSPACE_SOURCES = ["api", "dashboard", "slack", "linear", "github", "gitlab", "automation", "mothership"];
22352
22352
  var CLIENT_MESSAGE_SOURCES = ["web", "desktop", "mobile", "tui"];
@@ -22359,8 +22359,7 @@ var PLANS = {
22359
22359
  name: "Free Trial",
22360
22360
  monthlyPrice: 0,
22361
22361
  features: [
22362
- `${TRIAL_DURATION_DAYS} days free, no credit card required`,
22363
- `$${TRIAL_CREDIT_CENTS / 100} of usage across every workspace`,
22362
+ `$${TRIAL_CREDIT_CENTS / 100} of free usage, no credit card required`,
22364
22363
  "Unlimited repositories and environments",
22365
22364
  "Unlimited automations",
22366
22365
  "Warm pools and warm hooks",
@@ -22507,6 +22506,20 @@ var modelsDevCatalogSchema = external_exports.record(external_exports.string(),
22507
22506
  }))
22508
22507
  }));
22509
22508
 
22509
+ // ../shared/src/routes/reviews.ts
22510
+ var text = external_exports.string().trim().catch("");
22511
+ var optionalText = external_exports.string().trim().min(1).optional().catch(void 0);
22512
+ var pullRequestTourSchema = external_exports.object({
22513
+ /** The tour chat that wrote this file, so a rerun doesn't show the previous run's tour as in progress. */
22514
+ runId: optionalText,
22515
+ headSha: optionalText,
22516
+ status: external_exports.enum(["writing", "done"]).catch("writing"),
22517
+ summary: text,
22518
+ diagram: optionalText,
22519
+ files: external_exports.array(external_exports.object({ path: text, explanation: text })).catch([]),
22520
+ skip: external_exports.array(external_exports.object({ path: text, note: text })).catch([])
22521
+ });
22522
+
22510
22523
  // ../shared/src/languages.ts
22511
22524
  var EXT_TO_LANGUAGE = {
22512
22525
  ".ts": "typescript",
@@ -22961,14 +22974,14 @@ function coerceClaudePartialMessagePayload(payload) {
22961
22974
  const streamId = payload.streamId;
22962
22975
  if (typeof streamId !== "string" || !streamId) return null;
22963
22976
  const parentToolUseId = payload.parent_tool_use_id;
22964
- const text2 = typeof payload.text === "string" && payload.text ? payload.text : void 0;
22977
+ const text3 = typeof payload.text === "string" && payload.text ? payload.text : void 0;
22965
22978
  const thinking = typeof payload.thinking === "string" && payload.thinking ? payload.thinking : void 0;
22966
22979
  const tool = isRecord(payload.tool) && typeof payload.tool.id === "string" && typeof payload.tool.name === "string" ? typeof payload.tool.filePath === "string" ? { id: payload.tool.id, name: payload.tool.name, filePath: payload.tool.filePath } : typeof payload.tool.command === "string" ? { id: payload.tool.id, name: payload.tool.name, command: payload.tool.command } : void 0 : void 0;
22967
- if (!text2 && !thinking && !tool) return null;
22980
+ if (!text3 && !thinking && !tool) return null;
22968
22981
  return {
22969
22982
  streamId,
22970
22983
  parent_tool_use_id: typeof parentToolUseId === "string" ? parentToolUseId : null,
22971
- ...text2 ? { text: text2 } : {},
22984
+ ...text3 ? { text: text3 } : {},
22972
22985
  ...thinking ? { thinking } : {},
22973
22986
  ...tool ? { tool } : {},
22974
22987
  status: payload.status === "completed" ? "completed" : "in_progress"
@@ -23293,8 +23306,8 @@ function indexOrEnd(src, search, from) {
23293
23306
  const index = src.indexOf(search, from);
23294
23307
  return index < 0 ? src.length : index;
23295
23308
  }
23296
- function decodeAnsiC(text2) {
23297
- return text2.replace(/\\(x[0-9a-fA-F]{1,2}|u[0-9a-fA-F]{1,4}|[0-7]{1,3}|[\s\S])/g, (_match, escape) => {
23309
+ function decodeAnsiC(text3) {
23310
+ return text3.replace(/\\(x[0-9a-fA-F]{1,2}|u[0-9a-fA-F]{1,4}|[0-7]{1,3}|[\s\S])/g, (_match, escape) => {
23298
23311
  if (escape[0] === "x" || escape[0] === "u") return String.fromCharCode(parseInt(escape.slice(1), 16));
23299
23312
  if (/^[0-7]/.test(escape)) return String.fromCharCode(parseInt(escape, 8));
23300
23313
  return ANSI_C_ESCAPES[escape] ?? escape;
@@ -23311,8 +23324,8 @@ function staticOutput(argv, stdin) {
23311
23324
  if (flags.includes("n")) newline = false;
23312
23325
  if (flags.includes("e")) escapes = true;
23313
23326
  }
23314
- const text2 = args.join(" ");
23315
- return (escapes ? decodeAnsiC(text2) : text2) + (newline ? "\n" : "");
23327
+ const text3 = args.join(" ");
23328
+ return (escapes ? decodeAnsiC(text3) : text3) + (newline ? "\n" : "");
23316
23329
  }
23317
23330
  if (name === "printf" && args.length > 0) {
23318
23331
  const format = decodeAnsiC(args[0]);
@@ -23472,8 +23485,8 @@ function parseUntil(scope, start, closeParen) {
23472
23485
  let quoted = false;
23473
23486
  let redirect = null;
23474
23487
  let parens = 0;
23475
- const append = (text2, isQuoted = false) => {
23476
- word = (word ?? "") + text2;
23488
+ const append = (text3, isQuoted = false) => {
23489
+ word = (word ?? "") + text3;
23477
23490
  quoted || (quoted = isQuoted);
23478
23491
  };
23479
23492
  const endWord = () => {
@@ -24226,10 +24239,10 @@ var ENVIRONMENT_SETUP_LIMITS = {
24226
24239
  };
24227
24240
  var ENVIRONMENT_SETUP_VARIABLE_WAIT = { defaultMs: 5 * 6e4, maxMs: 15 * 6e4, pollMs: 5e3 };
24228
24241
  var VARIABLE_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
24229
- var text = (max) => max === void 0 ? external_exports.string().trim() : external_exports.string().trim().max(max);
24230
- var requiredText = (max) => text(max).min(1, "must not be empty");
24231
- var optionalText = (max) => text(max).nullish().transform((value) => value || null);
24232
- var clearableText = (max) => text(max).nullish().transform((value) => value === void 0 ? void 0 : value || null);
24242
+ var text2 = (max) => max === void 0 ? external_exports.string().trim() : external_exports.string().trim().max(max);
24243
+ var requiredText = (max) => text2(max).min(1, "must not be empty");
24244
+ var optionalText2 = (max) => text2(max).nullish().transform((value) => value || null);
24245
+ var clearableText = (max) => text2(max).nullish().transform((value) => value === void 0 ? void 0 : value || null);
24233
24246
  var list = (item, max) => max === void 0 ? external_exports.array(item) : external_exports.array(item).max(max);
24234
24247
  var ENVIRONMENT_SETUP_AUTHORED_TRIGGER_TYPES = ["cron", "github", "gitlab"];
24235
24248
  function isEnvironmentSetupAuthoredTriggerType(type) {
@@ -24245,9 +24258,9 @@ var carriedTriggerSchema = existingTriggerSchema.refine(
24245
24258
  );
24246
24259
  function automationSchema(limits) {
24247
24260
  const authored = external_exports.object({
24248
- name: text(limits.nameChars),
24249
- description: text(limits.descriptionChars),
24250
- prompt: text(limits.automationPromptChars),
24261
+ name: text2(limits.nameChars),
24262
+ description: text2(limits.descriptionChars),
24263
+ prompt: text2(limits.automationPromptChars),
24251
24264
  triggers: list(proposalTriggerSchema, limits.automationTriggers)
24252
24265
  });
24253
24266
  const updated = authored.extend({ triggers: list(external_exports.union([proposalTriggerSchema, carriedTriggerSchema]), limits.automationTriggers) });
@@ -24255,11 +24268,11 @@ function automationSchema(limits) {
24255
24268
  key: requiredText(limits.automationKeyChars),
24256
24269
  action: external_exports.enum(ENVIRONMENT_SETUP_AUTOMATION_ACTIONS).default("create"),
24257
24270
  automation_id: external_exports.string().regex(UUID_RE, "must be an automation id").nullable().default(null),
24258
- name: text().default(""),
24259
- description: optionalText().transform((value) => value ?? ""),
24260
- prompt: text().default(""),
24271
+ name: text2().default(""),
24272
+ description: optionalText2().transform((value) => value ?? ""),
24273
+ prompt: text2().default(""),
24261
24274
  triggers: list(existingTriggerSchema).default([]),
24262
- note: optionalText(limits.automationNoteChars)
24275
+ note: optionalText2(limits.automationNoteChars)
24263
24276
  }).superRefine((automation2, ctx) => {
24264
24277
  if (automation2.action === "create" && automation2.automation_id) {
24265
24278
  ctx.addIssue({ code: "custom", path: ["automation_id"], message: "belongs on an update, keep, or disable entry" });
@@ -24296,7 +24309,7 @@ function automationListSchema(limits) {
24296
24309
  }
24297
24310
  function environmentSchema(limits) {
24298
24311
  return external_exports.object({
24299
- name: optionalText(limits.nameChars).transform((value) => value ?? void 0),
24312
+ name: optionalText2(limits.nameChars).transform((value) => value ?? void 0),
24300
24313
  description: clearableText(limits.descriptionChars),
24301
24314
  system_prompt: clearableText(limits.systemPromptChars),
24302
24315
  start_hook: clearableText(limits.hookChars),
@@ -24306,21 +24319,21 @@ function environmentSchema(limits) {
24306
24319
  function variableSchema(limits, requiredDefault) {
24307
24320
  return external_exports.object({
24308
24321
  key: external_exports.string().regex(VARIABLE_KEY_RE, "must be a valid environment variable name").max(limits.variableKeyChars ?? Number.POSITIVE_INFINITY),
24309
- description: optionalText(limits.variableDescriptionChars).transform((value) => value ?? ""),
24322
+ description: optionalText2(limits.variableDescriptionChars).transform((value) => value ?? ""),
24310
24323
  required: external_exports.boolean().default(requiredDefault)
24311
24324
  });
24312
24325
  }
24313
24326
  function proposalSchema(limits) {
24314
24327
  return external_exports.object({
24315
24328
  summary: requiredText(limits.summaryChars),
24316
- stack: list(text(), limits.stackItems).default([]).transform((items) => items.filter(Boolean)),
24329
+ stack: list(text2(), limits.stackItems).default([]).transform((items) => items.filter(Boolean)),
24317
24330
  environment: environmentSchema(limits),
24318
24331
  variables: list(variableSchema(limits, false), limits.variables).default([]),
24319
24332
  automations: automationListSchema(limits),
24320
24333
  verification: list(external_exports.object({
24321
24334
  label: requiredText(limits.nameChars),
24322
24335
  status: external_exports.enum(ENVIRONMENT_SETUP_VERIFICATION_STATUSES),
24323
- detail: optionalText(limits.verificationDetailChars).transform((value) => value ?? void 0)
24336
+ detail: optionalText2(limits.verificationDetailChars).transform((value) => value ?? void 0)
24324
24337
  }), limits.verificationItems).default([]),
24325
24338
  media: list(external_exports.object({
24326
24339
  media_id: external_exports.string().regex(UUID_RE, "must be a media id"),
@@ -26243,12 +26256,12 @@ var DEFAULT_DEFAULT_SKILLS = {
26243
26256
  // ../shared/src/prompts.ts
26244
26257
  var REPLICAS_INSTRUCTIONS_TAG = "replicas_instructions";
26245
26258
  var MULTITASK_INSTRUCTIONS_TAG = "multitask_instructions";
26246
- function removeTag(text2, tag) {
26259
+ function removeTag(text3, tag) {
26247
26260
  const regex = new RegExp(`<${tag}>[\\s\\S]*?</${tag}>`, "g");
26248
- return text2.replace(regex, "").trim();
26261
+ return text3.replace(regex, "").trim();
26249
26262
  }
26250
- function removeReplicasInstructions(text2) {
26251
- return removeTag(text2, REPLICAS_INSTRUCTIONS_TAG);
26263
+ function removeReplicasInstructions(text3) {
26264
+ return removeTag(text3, REPLICAS_INSTRUCTIONS_TAG);
26252
26265
  }
26253
26266
  var MULTITASK_INSTRUCTIONS_BLOCK = new RegExp(`\\s*<${MULTITASK_INSTRUCTIONS_TAG}>\\n([\\s\\S]*?)\\n</${MULTITASK_INSTRUCTIONS_TAG}>`);
26254
26267
 
@@ -26270,8 +26283,8 @@ var TAG = "multitask_event";
26270
26283
  var BLOCK = new RegExp(`<${TAG}((?:\\s+\\w+="[^"]*")*)>\\n?([\\s\\S]*?)\\n?</${TAG}>`, "g");
26271
26284
  var ATTRIBUTE = /(\w+)="([^"]*)"/g;
26272
26285
  var unescapeAttribute = (value) => value.replace(/&lt;/g, "<").replace(/&quot;/g, '"').replace(/&amp;/g, "&");
26273
- function extractMultitaskEvents(text2) {
26274
- return [...text2.matchAll(BLOCK)].flatMap((match) => {
26286
+ function extractMultitaskEvents(text3) {
26287
+ return [...text3.matchAll(BLOCK)].flatMap((match) => {
26275
26288
  const attributes = Object.fromEntries([...match[1].matchAll(ATTRIBUTE)].map(([, key, value]) => [key, unescapeAttribute(value)]));
26276
26289
  const kind = MULTITASK_EVENT_KINDS.find((candidate) => candidate === attributes.kind);
26277
26290
  if (!kind || !attributes.id || !attributes.agent_id) return [];
@@ -26289,9 +26302,9 @@ function extractMultitaskEvents(text2) {
26289
26302
  }];
26290
26303
  });
26291
26304
  }
26292
- function parseMultitaskEvents(text2) {
26293
- const events = extractMultitaskEvents(text2);
26294
- return events.length > 0 && text2.replace(BLOCK, "").replaceAll(MERGED_MESSAGE_SEPARATOR.trim(), "").trim() === "" ? events : null;
26305
+ function parseMultitaskEvents(text3) {
26306
+ const events = extractMultitaskEvents(text3);
26307
+ return events.length > 0 && text3.replace(BLOCK, "").replaceAll(MERGED_MESSAGE_SEPARATOR.trim(), "").trim() === "" ? events : null;
26295
26308
  }
26296
26309
 
26297
26310
  // ../shared/src/frontmatter.ts
@@ -26345,9 +26358,9 @@ var MULTITASK_TOOL_ACTIONS = {
26345
26358
  var ATTACHMENT_PLACEHOLDER_REGEX = /^\[\d+ (?:(?:images?|files?)(?: and \d+ files?)? attached|(?:image )?attachments?)\]$/;
26346
26359
  var WALKTHROUGH_NOTE_REGEX = /(?:^|\n\n)<replicas_walkthrough path="([^"\n]+)" duration_seconds="(\d+)" audio="(true|false)">\n[^<]*\n<\/replicas_walkthrough>$/;
26347
26360
  var TRUNCATED_WALKTHROUGH_NOTE_REGEX = /(?:^|\n\n)<replicas_walkthrough path="([^"\n]*)(?:" duration_seconds="(\d*))?(?:" audio="(true)?)?[^<]*(?:<\/?[a-z_]*)?$/;
26348
- function stripAttachmentNote(text2) {
26349
- const match = text2.match(/(?:^|\n\n)<replicas_attachments>\nUploaded files are available at:((?:\n- .*)*)(?:\n<\/?[a-z_]*>?)?$/) ?? text2.match(/(?:^|\n\n)Uploaded files are available at:((?:\n- .*)*)$/);
26350
- let content = match ? text2.replace(match[0], "").trim() : text2;
26361
+ function stripAttachmentNote(text3) {
26362
+ const match = text3.match(/(?:^|\n\n)<replicas_attachments>\nUploaded files are available at:((?:\n- .*)*)(?:\n<\/?[a-z_]*>?)?$/) ?? text3.match(/(?:^|\n\n)Uploaded files are available at:((?:\n- .*)*)$/);
26363
+ let content = match ? text3.replace(match[0], "").trim() : text3;
26351
26364
  const walkthroughs = [];
26352
26365
  const truncated = WALKTHROUGH_NOTE_REGEX.test(content) ? null : content.match(TRUNCATED_WALKTHROUGH_NOTE_REGEX);
26353
26366
  if (truncated) {
@@ -26406,7 +26419,7 @@ function messagesForCodexTurn(turn) {
26406
26419
  return [{
26407
26420
  type: "reasoning",
26408
26421
  id: turn.id,
26409
- text: reasoning.map(({ text: text2 }) => text2.trim()).join("\n\n"),
26422
+ text: reasoning.map(({ text: text3 }) => text3.trim()).join("\n\n"),
26410
26423
  timestamp: reasoning[0].timestamp,
26411
26424
  status: reasoning.at(-1)?.status ?? "completed"
26412
26425
  }];
@@ -26883,8 +26896,8 @@ function getCursorAssistantText(event) {
26883
26896
  return getTextContent(message2?.content);
26884
26897
  }
26885
26898
  function getCursorThinkingText(event) {
26886
- const text2 = event.payload.text;
26887
- if (typeof text2 === "string") return text2;
26899
+ const text3 = event.payload.text;
26900
+ if (typeof text3 === "string") return text3;
26888
26901
  const message2 = isRecord(event.payload.message) ? event.payload.message : null;
26889
26902
  return typeof message2?.text === "string" ? message2.text : "";
26890
26903
  }
@@ -26935,8 +26948,8 @@ function parseCursorEvents(events) {
26935
26948
  continue;
26936
26949
  }
26937
26950
  if (event.type === "cursor-assistant") {
26938
- const text2 = getCursorAssistantText(event);
26939
- if (text2) {
26951
+ const text3 = getCursorAssistantText(event);
26952
+ if (text3) {
26940
26953
  const runId = cursorRunId(event);
26941
26954
  if (!activeAssistant || activeAssistant.runId !== runId) {
26942
26955
  const segment = runAssistantSegments.get(runId) ?? 0;
@@ -26955,15 +26968,15 @@ function parseCursorEvents(events) {
26955
26968
  if (message2?.type === "agent") {
26956
26969
  messages[activeAssistant.index] = {
26957
26970
  ...message2,
26958
- content: `${message2.content}${text2}`
26971
+ content: `${message2.content}${text3}`
26959
26972
  };
26960
26973
  }
26961
26974
  }
26962
26975
  continue;
26963
26976
  }
26964
26977
  if (event.type === "cursor-thinking") {
26965
- const text2 = getCursorThinkingText(event);
26966
- if (text2.trim()) {
26978
+ const text3 = getCursorThinkingText(event);
26979
+ if (text3.trim()) {
26967
26980
  const runId = cursorRunId(event);
26968
26981
  if (!activeThinking || activeThinking.runId !== runId) {
26969
26982
  const segment = runThinkingSegments.get(runId) ?? 0;
@@ -26983,7 +26996,7 @@ function parseCursorEvents(events) {
26983
26996
  if (message2?.type === "reasoning") {
26984
26997
  messages[activeThinking.index] = {
26985
26998
  ...message2,
26986
- content: `${message2.content}${text2}`,
26999
+ content: `${message2.content}${text3}`,
26987
27000
  status: "in_progress"
26988
27001
  };
26989
27002
  }
@@ -27015,12 +27028,12 @@ function parseCursorEvents(events) {
27015
27028
  }
27016
27029
  if (event.type === "cursor-task") {
27017
27030
  activeAssistant = null;
27018
- const text2 = event.payload.text;
27019
- if (typeof text2 === "string" && text2.trim()) {
27031
+ const text3 = event.payload.text;
27032
+ if (typeof text3 === "string" && text3.trim()) {
27020
27033
  messages.push({
27021
27034
  id: `cursor-task-${event.timestamp}-${messages.length}`,
27022
27035
  type: "agent",
27023
- content: text2,
27036
+ content: text3,
27024
27037
  timestamp: event.timestamp
27025
27038
  });
27026
27039
  }
@@ -27075,8 +27088,8 @@ var TRANSIENT_NETWORK_ERROR_PATTERNS = [
27075
27088
  ];
27076
27089
  var HTTP_CONTEXT_PATTERN = /(api error|request|response|status|http)/;
27077
27090
  var HTTP_STATUS_PATTERN = /(^|[^0-9])([1-5][0-9]{2})(?=$|[^0-9])/g;
27078
- function isTransientErrorText(text2, options = {}) {
27079
- const normalized = text2.toLowerCase();
27091
+ function isTransientErrorText(text3, options = {}) {
27092
+ const normalized = text3.toLowerCase();
27080
27093
  if (!normalized) return false;
27081
27094
  if (TRANSIENT_NETWORK_ERROR_PATTERNS.some((pattern) => pattern.test(normalized))) return true;
27082
27095
  if (options.includeRateLimit && /rate limit/.test(normalized)) return true;
@@ -27199,24 +27212,24 @@ function parseOpencodeEvents(events) {
27199
27212
  const time3 = isRecord(part.time) ? part.time : null;
27200
27213
  const timestamp = timestampFromMs(time3?.start, event.timestamp);
27201
27214
  if (part.type === "text") {
27202
- const text2 = typeof part.text === "string" ? part.text : "";
27203
- if (text2.trim()) {
27215
+ const text3 = typeof part.text === "string" ? part.text : "";
27216
+ if (text3.trim()) {
27204
27217
  upsertDisplayMessage(messages, {
27205
27218
  id,
27206
27219
  type: "agent",
27207
- content: text2,
27220
+ content: text3,
27208
27221
  timestamp
27209
27222
  });
27210
27223
  }
27211
27224
  continue;
27212
27225
  }
27213
27226
  if (part.type === "reasoning") {
27214
- const text2 = typeof part.text === "string" ? part.text : "";
27215
- if (text2.trim()) {
27227
+ const text3 = typeof part.text === "string" ? part.text : "";
27228
+ if (text3.trim()) {
27216
27229
  upsertDisplayMessage(messages, {
27217
27230
  id,
27218
27231
  type: "reasoning",
27219
- content: text2,
27232
+ content: text3,
27220
27233
  status: time3?.end ? "completed" : "in_progress",
27221
27234
  timestamp
27222
27235
  });
@@ -27384,7 +27397,7 @@ function assistantErrorMessage(value) {
27384
27397
  }
27385
27398
  function parsePiEvents(events) {
27386
27399
  const messages = [];
27387
- const text2 = /* @__PURE__ */ new Map();
27400
+ const text3 = /* @__PURE__ */ new Map();
27388
27401
  const thinking = /* @__PURE__ */ new Map();
27389
27402
  let activeMessageId = "assistant";
27390
27403
  for (const event of events) {
@@ -27415,9 +27428,9 @@ function parsePiEvents(events) {
27415
27428
  if (event.type === "pi-message_update") {
27416
27429
  const payload = nestedPayload(event);
27417
27430
  const id = typeof payload.id === "string" ? payload.id : activeMessageId;
27418
- if (payload.type === "text_delta" && typeof payload.delta === "string") text2.set(id, `${text2.get(id) ?? ""}${payload.delta}`);
27431
+ if (payload.type === "text_delta" && typeof payload.delta === "string") text3.set(id, `${text3.get(id) ?? ""}${payload.delta}`);
27419
27432
  if (payload.type === "thinking_delta" && typeof payload.delta === "string") thinking.set(id, `${thinking.get(id) ?? ""}${payload.delta}`);
27420
- const textContent = text2.get(id);
27433
+ const textContent = text3.get(id);
27421
27434
  const thinkingContent = thinking.get(id);
27422
27435
  if (textContent !== void 0) upsertDisplayMessage(messages, { id: `pi-${id}`, type: "agent", content: textContent, timestamp: event.timestamp });
27423
27436
  if (thinkingContent !== void 0) upsertDisplayMessage(messages, { id: `pi-thinking-${id}`, type: "reasoning", content: thinkingContent, status: "in_progress", timestamp: event.timestamp });
@@ -28567,7 +28580,7 @@ var headlessAgentRequestSchema = external_exports.object({
28567
28580
  });
28568
28581
 
28569
28582
  // ../shared/src/cli-version.ts
28570
- var CLI_VERSION = "0.3.49";
28583
+ var CLI_VERSION = "0.3.51";
28571
28584
 
28572
28585
  // ../shared/src/version.ts
28573
28586
  function compareVersions(v1, v2) {
@@ -29092,6 +29105,24 @@ var updatePresenceRequestSchema = external_exports.object({
29092
29105
  location: presenceLocationSchema.optional()
29093
29106
  });
29094
29107
 
29108
+ // ../shared/src/routes/review-messages.ts
29109
+ var sendPullRequestReviewMessageRequestSchema = external_exports.object({
29110
+ ...sendChatMessageRequestSchema.pick({
29111
+ message: true,
29112
+ messageId: true,
29113
+ submittedAt: true,
29114
+ model: true,
29115
+ images: true,
29116
+ canvasUploadIds: true,
29117
+ thinkingLevel: true,
29118
+ fastMode: true,
29119
+ ultrafastMode: true
29120
+ }).shape,
29121
+ /** Starts a new chat instead of continuing the PR's review chat. The provider only applies to a new chat. */
29122
+ newChat: external_exports.boolean().optional(),
29123
+ provider: external_exports.enum(VALID_AGENT_PROVIDERS).optional()
29124
+ });
29125
+
29095
29126
  // ../shared/src/audit-log.ts
29096
29127
  var AUDIT_LOG_ACTION = {
29097
29128
  CREATE: "create",
@@ -29227,10 +29258,7 @@ var EMAIL_KEYS = [
29227
29258
  "first_pr_merged",
29228
29259
  "day_5_shipped",
29229
29260
  "day_7_solo",
29230
- "day_14_no_pr",
29231
- "trial_day_7",
29232
- "trial_day_12",
29233
- "trial_expired"
29261
+ "day_14_no_pr"
29234
29262
  ];
29235
29263
  var MANUAL_EMAIL_TEMPLATE_KEYS = ["product_update"];
29236
29264
  var EMAIL_TEMPLATE_KEYS = [...EMAIL_KEYS, ...MANUAL_EMAIL_TEMPLATE_KEYS];
@@ -29693,8 +29721,8 @@ function renderAuthFlowStep(step, total, title2) {
29693
29721
  console.log(import_chalk2.default.bold(`
29694
29722
  ${step}/${total} ${title2}`));
29695
29723
  }
29696
- function renderAuthFlowDetail(text2) {
29697
- console.log(import_chalk2.default.gray(` ${text2}`));
29724
+ function renderAuthFlowDetail(text3) {
29725
+ console.log(import_chalk2.default.gray(` ${text3}`));
29698
29726
  }
29699
29727
  function renderAuthFlowSuccess(providerLabel, summary, target) {
29700
29728
  console.log(brand.bold(`
@@ -30967,8 +30995,8 @@ async function exchangeCodeForTokens2(code, state, expectedState, codeVerifier)
30967
30995
  body: JSON.stringify(payload)
30968
30996
  });
30969
30997
  if (!response.ok) {
30970
- const text2 = await response.text();
30971
- throw new Error(`Failed to exchange authorization code: ${response.status} ${text2}`);
30998
+ const text3 = await response.text();
30999
+ throw new Error(`Failed to exchange authorization code: ${response.status} ${text3}`);
30972
31000
  }
30973
31001
  const data = await response.json();
30974
31002
  return {
@@ -31832,9 +31860,9 @@ function formatStatus(status) {
31832
31860
  if (isWorkspaceSuspendedStatus(status)) return import_chalk20.default.gray(status);
31833
31861
  return status;
31834
31862
  }
31835
- function truncate(text2, maxLength) {
31836
- if (text2.length <= maxLength) return text2;
31837
- return text2.substring(0, maxLength) + "...";
31863
+ function truncate(text3, maxLength) {
31864
+ if (text3.length <= maxLength) return text3;
31865
+ return text3.substring(0, maxLength) + "...";
31838
31866
  }
31839
31867
  function formatDisplayMessage(message2) {
31840
31868
  const time3 = new Date(message2.timestamp).toLocaleTimeString();
@@ -32997,9 +33025,9 @@ function buildTriggersFromOptions(options, runAt, repositories) {
32997
33025
  }
32998
33026
  return triggers;
32999
33027
  }
33000
- function truncate2(text2, maxLength) {
33001
- if (text2.length <= maxLength) return text2;
33002
- return text2.substring(0, maxLength) + "...";
33028
+ function truncate2(text3, maxLength) {
33029
+ if (text3.length <= maxLength) return text3;
33030
+ return text3.substring(0, maxLength) + "...";
33003
33031
  }
33004
33032
  function formatAgentSummary(automation2) {
33005
33033
  const parts = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-cli",
3
- "version": "0.3.49",
3
+ "version": "0.3.51",
4
4
  "description": "CLI for managing Replicas workspaces - SSH into cloud dev environments with automatic port forwarding",
5
5
  "main": "dist/index.cjs",
6
6
  "bin": {