@meistrari/remy-cli 1.26.0-rc.3 → 1.26.0-rc.4

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/README.md CHANGED
@@ -80,7 +80,7 @@ Subagent work appears as named **Subagent · <name>** activity rather than messa
80
80
 
81
81
  Published files and Tela Pages appear in the timeline. File artifacts include their full Web preview URL; Tela Page rows include their title and canonical URL so you can open them directly from the terminal. Remy does not request or expose the Web-only temporary iframe capability for Tela Pages.
82
82
 
83
- Your messages and Remy's render as Markdown: headings, bold, italic, strikethrough, inline and fenced code, lists and task lists, quotes, tables, and links show formatted, with their syntax markers hidden. A Markdown link shows its label; a target that is not a plain HTTP or HTTPS URL stays visible as the original source text. The live assistant preview shows raw text until the finished message arrives, and a message with expanded workspace context shows its original text.
83
+ Your messages and Remy's render as Markdown: headings, bold, italic, strikethrough, inline and fenced code, lists and task lists, quotes, tables, and links show formatted, with their syntax markers hidden. A Markdown link shows its label; a target that is not a plain HTTP or HTTPS URL stays visible as the original source text. The live assistant preview shows raw text until the finished message arrives, and a message with expanded workspace context shows its original text. A message from Linear shows its issue as one dim line, `Linear issue ENG-123: <issue title>`, instead of the issue details passed to the agent, and leaves out the agent's note about Linear-hosted files.
84
84
 
85
85
  **Open links:** Ctrl+click an HTTP or HTTPS link in the conversation, including Markdown links and expanded activity links. Ordinary clicks and drag-to-copy keep their existing behavior. Terminals may reserve that gesture or use their own modifier for hyperlinks; `/links` or `Ctrl+L` provides a keyboard alternative; for a session connected to a Linear issue, the issue comes first. Select with arrows or `j`/`k`, press `Enter` to open the browser, or `c` to copy the complete URL. Browser opening uses the machine running Remy.
86
86
 
package/dist/remy.js CHANGED
@@ -35052,7 +35052,7 @@ function formatSessionJson({
35052
35052
  `;
35053
35053
  }
35054
35054
  // src/version.ts
35055
- var remyCliVersion = "1.26.0-rc.3";
35055
+ var remyCliVersion = "1.26.0-rc.4";
35056
35056
 
35057
35057
  // src/self-update.ts
35058
35058
  import { spawn as spawn2 } from "child_process";
@@ -35459,6 +35459,55 @@ function agentRuntimeIdentityKey(event) {
35459
35459
  return `${event.sessionId.length}:${event.sessionId}:${event.providerSessionId.length}:${event.providerSessionId}`;
35460
35460
  }
35461
35461
 
35462
+ // ../../packages/shared/src/linear-issue-context.ts
35463
+ var linearIssueContextBlock = {
35464
+ tag: "linear-issue-context",
35465
+ identifierAttribute: "identifier",
35466
+ urlAttribute: "url"
35467
+ };
35468
+ var linearHostedFileHintText = "Images and files in this Linear issue are hosted by Linear. To view or download them, use the Linear MCP when this session has it: `extract_images` for images in the issue or its comments, and `get_attachment` for issue attachments.";
35469
+ var linearIssueContextBlockPattern = new RegExp(`^<${linearIssueContextBlock.tag} ${linearIssueContextBlock.identifierAttribute}="([^"]*)" ${linearIssueContextBlock.urlAttribute}="[^"]*">\\n([\\s\\S]*)\\n</${linearIssueContextBlock.tag}>$`, "u");
35470
+ var linearIssueTitlePattern = /<title>([^<]*)<\/title>/u;
35471
+ function withoutLinearAgentParts({ provider, parts }) {
35472
+ if (provider !== "linear")
35473
+ return { parts: [...parts], issueContext: null };
35474
+ const personParts = [];
35475
+ let issueContext = null;
35476
+ for (const [index, part] of parts.entries()) {
35477
+ if (index === 0 || part.type !== "text" || part.text === undefined) {
35478
+ personParts.push(part);
35479
+ continue;
35480
+ }
35481
+ if (part.text === linearHostedFileHintText)
35482
+ continue;
35483
+ const parsed = issueContext === null ? parseLinearIssueContextBlock(part.text) : null;
35484
+ if (parsed === null)
35485
+ personParts.push(part);
35486
+ else
35487
+ issueContext = parsed;
35488
+ }
35489
+ return { parts: personParts, issueContext };
35490
+ }
35491
+ function parseLinearIssueContextBlock(text) {
35492
+ const match = linearIssueContextBlockPattern.exec(text);
35493
+ if (match === null)
35494
+ return null;
35495
+ const [, identifier = "", content = ""] = match;
35496
+ const title = unescapeXml(linearIssueTitlePattern.exec(content)?.[1] ?? "").trim();
35497
+ return { identifier: unescapeXml(identifier), title: title === "" ? null : title, content };
35498
+ }
35499
+ var xmlNamedEntities = { lt: "<", gt: ">", quot: '"', apos: "'", amp: "&" };
35500
+ var xmlEntityPattern = /&(?:#(\d+)|#x([\da-f]+)|(lt|gt|quot|apos|amp));/giu;
35501
+ var maxCodePoint = 1114111;
35502
+ function unescapeXml(value) {
35503
+ return value.replace(xmlEntityPattern, (entity, decimal, hexadecimal, name) => {
35504
+ if (name !== undefined)
35505
+ return xmlNamedEntities[name.toLowerCase()] ?? entity;
35506
+ const codePoint = decimal === undefined ? Number.parseInt(hexadecimal ?? "", 16) : Number.parseInt(decimal, 10);
35507
+ return codePoint <= maxCodePoint ? String.fromCodePoint(codePoint) : entity;
35508
+ });
35509
+ }
35510
+
35462
35511
  // src/sessions/event-url.ts
35463
35512
  function sessionEventWebUrl({ sessionWebUrl, eventId }) {
35464
35513
  if (sessionWebUrl === undefined)
@@ -35842,7 +35891,8 @@ function projectSessionNotificationTurnAssociated({
35842
35891
  function projectSessionMessageCreated({ state, event, occurredAt }) {
35843
35892
  if (state.transcript.some((item) => item.kind === "message" && item.messageId === event.payload.messageId))
35844
35893
  return state;
35845
- const text = event.payload.parts.map(sessionMessagePartText).join("");
35894
+ const { parts, issueContext } = withoutLinearAgentParts({ provider: event.payload.source.provider, parts: event.payload.parts });
35895
+ const text = parts.map(sessionMessagePartText).join("");
35846
35896
  const creatorLabel = event.payload.creator.type === "user" && event.payload.creator.status === "deleted" ? "Deleted user" : event.payload.creator.name;
35847
35897
  return {
35848
35898
  ...state,
@@ -35854,6 +35904,7 @@ function projectSessionMessageCreated({ state, event, occurredAt }) {
35854
35904
  occurredAt,
35855
35905
  author: { label: creatorLabel, role: "human", source: messageSourceLabel(event.payload.source.provider) },
35856
35906
  text,
35907
+ ...issueContext === null ? {} : { linearIssue: { identifier: issueContext.identifier, title: issueContext.title } },
35857
35908
  attachments: event.payload.attachments.map((attachment) => ({ id: attachment.attachmentId, filename: attachment.filename, mediaType: attachment.mediaType }))
35858
35909
  }]
35859
35910
  };
@@ -45392,6 +45443,7 @@ function renderTimelineItem(item, activityExpanded) {
45392
45443
  return joinStyled([
45393
45444
  header,
45394
45445
  renderMessageBody({ text: item.text, role: item.author.role, expandedWorkspaceContext: activityExpanded }),
45446
+ ...item.linearIssue ? [renderLinearIssueLine(item.linearIssue)] : [],
45395
45447
  ...attachments.chunks.length > 0 ? [attachments] : []
45396
45448
  ], `
45397
45449
  `);
@@ -45413,6 +45465,10 @@ function renderTimelineItem(item, activityExpanded) {
45413
45465
  ...item.previewUrl ? [dim7(fg12(PALETTE.dimText)(` (${item.previewUrl})`))] : []
45414
45466
  ]);
45415
45467
  }
45468
+ function renderLinearIssueLine({ identifier, title }) {
45469
+ const label = title === null ? `Linear issue ${identifier}` : `Linear issue ${identifier}: ${title}`;
45470
+ return new StyledText11([dim7(fg12(PALETTE.dimText)(terminalSafeText(label).replace(/\s+/g, " ").trim()))]);
45471
+ }
45416
45472
  var collapsedPlanItemLimit = 5;
45417
45473
  function renderPlan({ item, expanded }) {
45418
45474
  if (item.items.length === 0)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meistrari/remy-cli",
3
- "version": "1.26.0-rc.3",
3
+ "version": "1.26.0-rc.4",
4
4
  "description": "Remy, the Coding Agent terminal client.",
5
5
  "type": "module",
6
6
  "bin": {