replicas-cli 0.2.275 → 0.2.277

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.mjs +115 -42
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -9236,7 +9236,7 @@ var HOOK_EXEC_MAX_BUFFER_BYTES = 10 * 1024 * 1024;
9236
9236
  var REPLICAS_CONFIG_FILENAMES = ["replicas.json", "replicas.yaml", "replicas.yml"];
9237
9237
 
9238
9238
  // ../shared/src/cli-version.ts
9239
- var CLI_VERSION = "0.2.275";
9239
+ var CLI_VERSION = "0.2.277";
9240
9240
 
9241
9241
  // ../shared/src/engine/environment.ts
9242
9242
  var DESKTOP_NOVNC_PORT = 6080;
@@ -10621,6 +10621,8 @@ function parseInlineDiffCommentLocation(location) {
10621
10621
  function parseCIFailure(content) {
10622
10622
  if (!content.startsWith("# CI/CD Workflow Failed")) return null;
10623
10623
  const prMatch = content.match(/Pull Request #(\d+)/);
10624
+ const mrMatch = content.match(/Merge Request !(\d+)/);
10625
+ const requestMatch = prMatch ?? mrMatch;
10624
10626
  const workflowNameMatch = content.match(/\*\*Workflow Name:\*\*\s*(.+)/);
10625
10627
  const workflowFileMatch = content.match(/\*\*Workflow File:\*\*\s*(.+)/);
10626
10628
  const conclusionMatch = content.match(/\*\*Conclusion:\*\*\s*(.+)/);
@@ -10630,10 +10632,11 @@ function parseCIFailure(content) {
10630
10632
  );
10631
10633
  const prUrlMatch = content.match(/\*\*PR URL:\*\*\s*(.+)/);
10632
10634
  const fileUrlMatch = content.match(/\*\*File URL:\*\*\s*(.+)/);
10633
- if (!prMatch) return null;
10635
+ if (!requestMatch) return null;
10634
10636
  return {
10635
10637
  source: "ci_failure",
10636
- prNumber: parseInt(prMatch[1], 10),
10638
+ prNumber: parseInt(requestMatch[1], 10),
10639
+ isMergeRequest: !prMatch && !!mrMatch,
10637
10640
  workflowName: workflowNameMatch?.[1]?.trim() ?? "Unknown",
10638
10641
  workflowFile: workflowFileMatch?.[1]?.trim() ?? "",
10639
10642
  conclusion: conclusionMatch?.[1]?.trim() ?? "failure",
@@ -10644,45 +10647,74 @@ function parseCIFailure(content) {
10644
10647
  };
10645
10648
  }
10646
10649
  function parseGitHubIssueNew(content) {
10647
- const headerMatch = content.match(/^# Task: GitHub Issue #(\d+) - (.+)$/m);
10650
+ const fields = parseIssueNewFields(content, /^# Task: GitHub Issue #(\d+) - (.+)$/m);
10651
+ if (!fields) return null;
10652
+ const userUrlMatch = content.match(/\*\*User URL:\*\*\s*(.+)/);
10653
+ return {
10654
+ source: "github_issue_new",
10655
+ ...fields,
10656
+ userUrl: userUrlMatch?.[1]?.trim()
10657
+ };
10658
+ }
10659
+ function parseGitHubIssueExisting(content) {
10660
+ const fields = parseIssueExistingFields(content, /^You received a new comment on GitHub Issue #(\d+)\./);
10661
+ if (!fields) return null;
10662
+ const userUrlMatch = content.match(/\*\*User URL:\*\*\s*(.+)/);
10663
+ return {
10664
+ source: "github_issue_existing",
10665
+ ...fields,
10666
+ userUrl: userUrlMatch?.[1]?.trim()
10667
+ };
10668
+ }
10669
+ function parseGitLabIssueNew(content) {
10670
+ const fields = parseIssueNewFields(content, /^# Task: GitLab Issue #(\d+) - (.+)$/m);
10671
+ if (!fields) return null;
10672
+ const userUrlMatch = content.match(/\*\*User URL:\*\*\s*(.+)/);
10673
+ return {
10674
+ source: "gitlab_issue_new",
10675
+ ...fields,
10676
+ userUrl: userUrlMatch?.[1]?.trim()
10677
+ };
10678
+ }
10679
+ function parseIssueNewFields(content, headerPattern) {
10680
+ const headerMatch = content.match(headerPattern);
10648
10681
  if (!headerMatch) return null;
10649
- const issueNumber = parseInt(headerMatch[1], 10);
10650
- const issueTitle = headerMatch[2].trim();
10651
10682
  const descMatch = content.match(/## Issue Description\n([\s\S]*?)(?=\n## |$)/);
10652
10683
  const triggerMatch = content.match(
10653
10684
  /## Triggering Comment from @(\S+)\n([\s\S]*?)(?=\n\*\*(?:PR|Issue|User|File) URL:\*\*|\n## |$)/
10654
10685
  );
10655
10686
  const issueUrlMatch = content.match(/\*\*Issue URL:\*\*\s*(.+)/);
10656
- const userUrlMatch = content.match(/\*\*User URL:\*\*\s*(.+)/);
10657
10687
  return {
10658
- source: "github_issue_new",
10659
- issueNumber,
10660
- issueTitle,
10688
+ issueNumber: parseInt(headerMatch[1], 10),
10689
+ issueTitle: headerMatch[2].trim(),
10661
10690
  issueDescription: descMatch?.[1]?.trim() ?? "",
10662
10691
  triggeringUser: triggerMatch?.[1] ?? "",
10663
10692
  triggeringComment: triggerMatch?.[2]?.trim() ?? "",
10664
- issueUrl: issueUrlMatch?.[1]?.trim(),
10693
+ issueUrl: issueUrlMatch?.[1]?.trim()
10694
+ };
10695
+ }
10696
+ function parseGitLabIssueExisting(content) {
10697
+ const fields = parseIssueExistingFields(content, /^You received a new comment on GitLab Issue #(\d+)\./);
10698
+ if (!fields) return null;
10699
+ const userUrlMatch = content.match(/\*\*User URL:\*\*\s*(.+)/);
10700
+ return {
10701
+ source: "gitlab_issue_existing",
10702
+ ...fields,
10665
10703
  userUrl: userUrlMatch?.[1]?.trim()
10666
10704
  };
10667
10705
  }
10668
- function parseGitHubIssueExisting(content) {
10669
- const headerMatch = content.match(
10670
- /^You received a new comment on GitHub Issue #(\d+)\./
10671
- );
10706
+ function parseIssueExistingFields(content, headerPattern) {
10707
+ const headerMatch = content.match(headerPattern);
10672
10708
  if (!headerMatch) return null;
10673
- const issueNumber = parseInt(headerMatch[1], 10);
10674
10709
  const commentMatch = content.match(
10675
10710
  /Comment from @(\S+):\n([\s\S]*?)(?=\n\*\*(?:PR|Issue|User|File) URL:\*\*|\nIMPORTANT INSTRUCTIONS:)/
10676
10711
  );
10677
10712
  const issueUrlMatch = content.match(/\*\*Issue URL:\*\*\s*(.+)/);
10678
- const userUrlMatch = content.match(/\*\*User URL:\*\*\s*(.+)/);
10679
10713
  return {
10680
- source: "github_issue_existing",
10681
- issueNumber,
10714
+ issueNumber: parseInt(headerMatch[1], 10),
10682
10715
  commentUser: commentMatch?.[1] ?? "",
10683
10716
  commentBody: commentMatch?.[2]?.trim() ?? "",
10684
- issueUrl: issueUrlMatch?.[1]?.trim(),
10685
- userUrl: userUrlMatch?.[1]?.trim()
10717
+ issueUrl: issueUrlMatch?.[1]?.trim()
10686
10718
  };
10687
10719
  }
10688
10720
  function parseGitHubPRNew(content) {
@@ -10768,25 +10800,51 @@ function parseGitHubPRExistingReview(content) {
10768
10800
  };
10769
10801
  }
10770
10802
  function parseGitHubPRExistingGeneral(content) {
10771
- const headerMatch = content.match(
10772
- /^You received a comment on Pull Request #(\d+)\./m
10773
- );
10774
- if (!headerMatch) return null;
10775
- const prNumber = parseInt(headerMatch[1], 10);
10776
- const commentMatch = content.match(
10777
- /Comment from @(\S+):\n([\s\S]*?)(?=\n\*\*(?:PR|Issue|User|File) URL:\*\*|\nIMPORTANT INSTRUCTIONS:)/
10803
+ const fields = parseHostReviewThreadFields(
10804
+ content,
10805
+ /^You received a comment on Pull Request #(\d+)\./m,
10806
+ /Comment from @(\S+):\n([\s\S]*?)(?=\n\*\*(?:PR|Issue|User|File) URL:\*\*|\nIMPORTANT INSTRUCTIONS:)/,
10807
+ /\*\*PR URL:\*\*\s*(.+)/
10778
10808
  );
10779
- const prUrlMatch = content.match(/\*\*PR URL:\*\*\s*(.+)/);
10809
+ if (!fields) return null;
10780
10810
  const userUrlMatch = content.match(/\*\*User URL:\*\*\s*(.+)/);
10781
10811
  return {
10782
10812
  source: "github_pr_existing_general",
10783
- prNumber,
10784
- commentUser: commentMatch?.[1] ?? "",
10785
- commentBody: commentMatch?.[2]?.trim() ?? "",
10786
- prUrl: prUrlMatch?.[1]?.trim(),
10813
+ prNumber: fields.itemNumber,
10814
+ commentUser: fields.commentUser,
10815
+ commentBody: fields.commentBody,
10816
+ prUrl: fields.itemUrl,
10787
10817
  userUrl: userUrlMatch?.[1]?.trim()
10788
10818
  };
10789
10819
  }
10820
+ function parseGitLabMRExistingGeneral(content) {
10821
+ const fields = parseHostReviewThreadFields(
10822
+ content,
10823
+ /^You received a comment on GitLab Merge Request !(\d+)\./m,
10824
+ /Comment from @?([^:\n]+):\n([\s\S]*?)(?=\n\*\*(?:Merge Request|Comment)(?: URL)?:\*\*|\nIMPORTANT INSTRUCTIONS:)/,
10825
+ /\*\*Comment URL:\*\*\s*(.+)/
10826
+ );
10827
+ if (!fields) return null;
10828
+ return {
10829
+ source: "gitlab_mr_existing_general",
10830
+ mergeRequestIid: fields.itemNumber,
10831
+ commentUser: fields.commentUser,
10832
+ commentBody: fields.commentBody,
10833
+ commentUrl: fields.itemUrl
10834
+ };
10835
+ }
10836
+ function parseHostReviewThreadFields(content, headerPattern, commentPattern, itemUrlPattern) {
10837
+ const headerMatch = content.match(headerPattern);
10838
+ if (!headerMatch) return null;
10839
+ const commentMatch = content.match(commentPattern);
10840
+ const itemUrlMatch = content.match(itemUrlPattern);
10841
+ return {
10842
+ itemNumber: parseInt(headerMatch[1], 10),
10843
+ commentUser: commentMatch?.[1]?.trim() ?? "",
10844
+ commentBody: commentMatch?.[2]?.trim() ?? "",
10845
+ itemUrl: itemUrlMatch?.[1]?.trim()
10846
+ };
10847
+ }
10790
10848
  function parseSlackTask(content) {
10791
10849
  if (!content.startsWith("# Task from Slack")) return null;
10792
10850
  const targetMatch = content.match(/## Workspace Target\nWorking in: (.+?)(?=\n\*\*(?:Thread|Target) URL:\*\*|\n\n)/);
@@ -10879,7 +10937,7 @@ function parseAutomationTriggered(content) {
10879
10937
  };
10880
10938
  }
10881
10939
  function parseSingleMessage(content) {
10882
- return parseCIFailure(content) ?? parseGitHubIssueNew(content) ?? parseGitHubIssueExisting(content) ?? parseGitHubPRNew(content) ?? parseGitHubPRExistingPRReview(content) ?? parseGitHubPRExistingReview(content) ?? parseGitHubPRExistingGeneral(content) ?? parseSlackTask(content) ?? parseLinearIssue(content) ?? parseAutomationTriggered(content) ?? parseInlineDiffComments(content) ?? parsePlanQuote(content) ?? { source: "raw", content };
10940
+ return parseCIFailure(content) ?? parseGitHubIssueNew(content) ?? parseGitHubIssueExisting(content) ?? parseGitLabIssueNew(content) ?? parseGitLabIssueExisting(content) ?? parseGitHubPRNew(content) ?? parseGitHubPRExistingPRReview(content) ?? parseGitHubPRExistingReview(content) ?? parseGitHubPRExistingGeneral(content) ?? parseGitLabMRExistingGeneral(content) ?? parseSlackTask(content) ?? parseLinearIssue(content) ?? parseAutomationTriggered(content) ?? parseInlineDiffComments(content) ?? parsePlanQuote(content) ?? { source: "raw", content };
10883
10941
  }
10884
10942
  function parseMerged(content) {
10885
10943
  if (!content.includes(MERGED_MESSAGE_SEPARATOR)) return null;
@@ -10901,10 +10959,13 @@ var SOURCE_CONFIG = {
10901
10959
  linear_issue: { label: "Linear", color: "#5E6AD2" },
10902
10960
  github_issue_new: { label: "GitHub Issue", color: "#8b949e" },
10903
10961
  github_issue_existing: { label: "GitHub Issue", color: "#8b949e" },
10962
+ gitlab_issue_new: { label: "GitLab Issue", color: "#fc6d26" },
10963
+ gitlab_issue_existing: { label: "GitLab Issue", color: "#fc6d26" },
10904
10964
  github_pr_new: { label: "GitHub PR", color: "#8b949e" },
10905
10965
  github_pr_existing_review: { label: "Code Review", color: "#8b949e" },
10906
10966
  github_pr_existing_pr_review: { label: "PR Review", color: "#8b949e" },
10907
10967
  github_pr_existing_general: { label: "GitHub PR", color: "#8b949e" },
10968
+ gitlab_mr_existing_general: { label: "GitLab MR", color: "#fc6d26" },
10908
10969
  slack_task: { label: "Slack", color: "#BF6CC2" },
10909
10970
  automation_triggered: { label: "Automation", color: "#f59e0b" },
10910
10971
  plan_quote: { label: "Plan", color: "#3eeba3" },
@@ -15489,17 +15550,19 @@ function ExpandableDiffSection({ label, diffContent, filePath }) {
15489
15550
  ] });
15490
15551
  }
15491
15552
  function CIFailureMessage({ data }) {
15553
+ const requestLabel = data.isMergeRequest ? "MR" : "PR";
15554
+ const requestRef = `${data.isMergeRequest ? "!" : "#"}${data.prNumber}`;
15492
15555
  return /* @__PURE__ */ jsxs5("box", { flexDirection: "column", gap: 0, children: [
15493
15556
  /* @__PURE__ */ jsxs5("box", { flexDirection: "row", gap: 1, children: [
15494
15557
  /* @__PURE__ */ jsx5(SourceBadge, { source: "ci_failure" }),
15495
- /* @__PURE__ */ jsx5(MetadataPill, { label: "PR", value: `#${data.prNumber}` }),
15558
+ /* @__PURE__ */ jsx5(MetadataPill, { label: requestLabel, value: requestRef }),
15496
15559
  /* @__PURE__ */ jsx5(MetadataPill, { label: "Workflow", value: data.workflowName }),
15497
15560
  /* @__PURE__ */ jsx5(MetadataPill, { label: "Status", value: data.conclusion })
15498
15561
  ] }),
15499
15562
  /* @__PURE__ */ jsxs5("text", { fg: "#ffffff", children: [
15500
15563
  "Workflow ",
15501
15564
  /* @__PURE__ */ jsx5("span", { fg: "#ff4444", children: data.conclusionText }),
15502
- " on PR #" + data.prNumber
15565
+ ` on ${requestLabel} ${requestRef}`
15503
15566
  ] }),
15504
15567
  data.workflowFile && /* @__PURE__ */ jsx5(MetadataPill, { label: "File", value: data.workflowFile }),
15505
15568
  data.runUrl && /* @__PURE__ */ jsx5(MetadataPill, { label: "Run", value: data.runUrl })
@@ -15517,10 +15580,13 @@ function LinearIssueMessage({ data }) {
15517
15580
  data.parentIssue && /* @__PURE__ */ jsx5(ExpandableSection, { label: `Parent: ${data.parentIssue.identifier} - ${data.parentIssue.title}`, children: data.parentIssue.description })
15518
15581
  ] });
15519
15582
  }
15520
- function GitHubIssueNewMessage({ data }) {
15583
+ function HostIssueNewMessage({
15584
+ data,
15585
+ source
15586
+ }) {
15521
15587
  return /* @__PURE__ */ jsxs5("box", { flexDirection: "column", gap: 0, children: [
15522
15588
  /* @__PURE__ */ jsxs5("box", { flexDirection: "row", gap: 1, children: [
15523
- /* @__PURE__ */ jsx5(SourceBadge, { source: "github_issue_new" }),
15589
+ /* @__PURE__ */ jsx5(SourceBadge, { source }),
15524
15590
  /* @__PURE__ */ jsx5(MetadataPill, { label: "Issue", value: `#${data.issueNumber}` }),
15525
15591
  data.triggeringUser && /* @__PURE__ */ jsx5(MetadataPill, { label: "From", value: `@${data.triggeringUser}` })
15526
15592
  ] }),
@@ -15529,10 +15595,13 @@ function GitHubIssueNewMessage({ data }) {
15529
15595
  /* @__PURE__ */ jsx5(ExpandableSection, { label: "Issue description", children: data.issueDescription })
15530
15596
  ] });
15531
15597
  }
15532
- function GitHubIssueExistingMessage({ data }) {
15598
+ function HostIssueExistingMessage({
15599
+ data,
15600
+ source
15601
+ }) {
15533
15602
  return /* @__PURE__ */ jsxs5("box", { flexDirection: "column", gap: 0, children: [
15534
15603
  /* @__PURE__ */ jsxs5("box", { flexDirection: "row", gap: 1, children: [
15535
- /* @__PURE__ */ jsx5(SourceBadge, { source: "github_issue_existing" }),
15604
+ /* @__PURE__ */ jsx5(SourceBadge, { source }),
15536
15605
  /* @__PURE__ */ jsx5(MetadataPill, { label: "Issue", value: `#${data.issueNumber}` }),
15537
15606
  data.commentUser && /* @__PURE__ */ jsx5(MetadataPill, { label: "From", value: `@${data.commentUser}` })
15538
15607
  ] }),
@@ -15624,9 +15693,13 @@ function StructuredUserMessage({ parsed }) {
15624
15693
  case "linear_issue":
15625
15694
  return /* @__PURE__ */ jsx5(LinearIssueMessage, { data: parsed });
15626
15695
  case "github_issue_new":
15627
- return /* @__PURE__ */ jsx5(GitHubIssueNewMessage, { data: parsed });
15696
+ return /* @__PURE__ */ jsx5(HostIssueNewMessage, { data: parsed, source: "github_issue_new" });
15628
15697
  case "github_issue_existing":
15629
- return /* @__PURE__ */ jsx5(GitHubIssueExistingMessage, { data: parsed });
15698
+ return /* @__PURE__ */ jsx5(HostIssueExistingMessage, { data: parsed, source: "github_issue_existing" });
15699
+ case "gitlab_issue_new":
15700
+ return /* @__PURE__ */ jsx5(HostIssueNewMessage, { data: parsed, source: "gitlab_issue_new" });
15701
+ case "gitlab_issue_existing":
15702
+ return /* @__PURE__ */ jsx5(HostIssueExistingMessage, { data: parsed, source: "gitlab_issue_existing" });
15630
15703
  case "github_pr_new":
15631
15704
  return /* @__PURE__ */ jsx5(GitHubPRNewMessage, { data: parsed });
15632
15705
  case "github_pr_existing_review":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-cli",
3
- "version": "0.2.275",
3
+ "version": "0.2.277",
4
4
  "description": "CLI for managing Replicas workspaces - SSH into cloud dev environments with automatic port forwarding",
5
5
  "main": "dist/index.mjs",
6
6
  "bin": {