Skip to content

Add Discord markdown link length warnings for agents - #81

Merged
baanish merged 3 commits into
mainfrom
cursor/discord-markdown-link-warning-aa2e
Jun 20, 2026
Merged

Add Discord markdown link length warnings for agents#81
baanish merged 3 commits into
mainfrom
cursor/discord-markdown-link-warning-aa2e

Conversation

@baanish

@baanish baanish commented Jun 20, 2026

Copy link
Copy Markdown
Owner

Summary

Agents generating agent-render links can now detect when a formatted Discord markdown link [label](url) exceeds Discord's 2,000-character message limit.

  • Added DISCORD_MESSAGE_MAX_LENGTH, buildMarkdownLinkShareInfo, and related helpers in src/lib/markdown-link.ts
  • Extended createGeneratedArtifactLink* results with markdownLink, markdownLinkLength, and discordMarkdownLinkWarning
  • Surfaced the warning in the link creator output and artifact viewer toolbar
  • Updated skills/agent-render-linking/SKILL.md, docs, AGENTS.md, and the agent-skills digest

Agent contract

When discordMarkdownLinkWarning is non-null, agents should surface the warning and split the bundle into smaller artifacts, sending separate markdown links across multiple Discord messages.

Testing

  • npm run test -- tests/markdown-link.test.ts tests/link-creator.test.ts tests/components/link-creator.test.tsx
  • npm run lint
  • npm run typecheck
Open in Web Open in Cursor 

Summary by CodeRabbit

  • New Features
    • Link creator now provides ready-to-paste markdown links (with length) alongside URLs, including a dedicated copy action.
    • Viewer and sharing UI surface Discord-specific notices when markdown links may exceed Discord’s 2,000-character limit, with guidance to split into multiple messages.
  • Documentation
    • Updated markdown-link sharing guidance and explicitly documented Discord length behavior.
    • Added payload-link constraint details for Discord-formatted markdown links.
  • Style
    • Improved warning/error visuals for link-sharing and creator states.
  • Tests
    • Expanded coverage for markdown link length and Discord warning/notice behavior.

Expose helpers to detect when a formatted [label](url) exceeds Discord's
2000-character message limit, return discordMarkdownLinkWarning from link
generation, and surface the warning in the viewer and link creator UI.
Update the agent skill, docs, and agent-skills digest accordingly.

Co-authored-by: Aanish Bhirud <baanish@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 923b5831-5529-4194-abeb-f8245bbe992b

📥 Commits

Reviewing files that changed from the base of the PR and between 4c17ffe and 2530695.

📒 Files selected for processing (4)
  • src/components/home/link-creator.tsx
  • src/components/viewer/artifact-stage.tsx
  • src/lib/markdown-link.ts
  • tests/markdown-link.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/components/viewer/artifact-stage.tsx
  • src/lib/markdown-link.ts

📝 Walkthrough

Walkthrough

Adds Discord per-message character-limit (2000) detection for markdown links. A new src/lib/markdown-link.ts module introduces DISCORD_MESSAGE_MAX_LENGTH, MarkdownLinkShareInfo, and related helpers. GeneratedArtifactLink is extended with markdownLink, markdownLinkLength, and discordMarkdownLinkWarning fields. Both LinkCreator and ArtifactStage UI components surface this metadata. Documentation and skill guidance are updated accordingly.

Changes

Discord Markdown Link Warnings

Layer / File(s) Summary
Core markdown-link library
src/lib/markdown-link.ts
Adds DISCORD_MESSAGE_MAX_LENGTH constant (2000), MarkdownLinkShareInfo type, and exported helpers isDiscordMarkdownLinkTooLong, getDiscordMarkdownLinkWarning, getDiscordMarkdownLinkViewerNotice, and buildMarkdownLinkShareInfo.
Payload link-creator: type extension and share info
src/lib/payload/link-creator.ts
Imports buildMarkdownLinkShareInfo, extends GeneratedArtifactLink with markdownLink/markdownLinkLength/discordMarkdownLinkWarning, adds buildGeneratedLinkShareInfo internal helper, and populates the new fields in both sync and async creator return values.
Link-creator component: markdown link output and copy action
src/components/home/link-creator.tsx
Adds markdownLinkCopyState, handleCopyMarkdownLink copy action, markdown-link textarea display, markdownLinkLength metric, and "Copy markdown link" button replacing the prior URL copy action. Resets markdown copy state on draft changes and request lifecycle.
Artifact-stage component: Discord warning integration
src/components/viewer/artifact-stage.tsx
Updates imports to use buildMarkdownLinkShareInfo and getDiscordMarkdownLinkViewerNotice. Adds pageHref state, computes memoized markdownLinkShareInfo, updates copy handler to use precomputed markdown link, and conditionally renders Discord viewer notice above artifact selector.
CSS styling for warning states
src/app/globals.css
Adds .creator-warning-state, .creator-error-state, and .artifact-share-warning CSS classes with warning-themed styling. Extends existing multi-selector rule to include warning and error state elements.
Tests
tests/markdown-link.test.ts, tests/link-creator.test.ts, tests/components/link-creator.test.tsx
Expands markdown-link tests with Discord-limit detection, buildMarkdownLinkShareInfo, and viewer-notice cases. Extends link-creator tests with markdownLink/markdownLinkLength/discordMarkdownLinkWarning assertions and long-link warning test. Updates component test helper to derive shareInfo via buildMarkdownLinkShareInfo.
Docs, SKILL.md guidance, and skill digest
AGENTS.md, docs/payload-format.md, skills/agent-render-linking/SKILL.md, public/.well-known/agent-skills/index.json
Documents Discord 2,000-character link length constraint in AGENTS.md and docs/payload-format.md; adds "Ready-to-send markdown link" section, revised Practical limits, Discord subsection, and Good defaults bullet in SKILL.md; updates the skill digest hash.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • baanish/agent-render#68: Both PRs modify src/lib/markdown-link.ts for markdown inline link generation—main PR builds Discord length-aware buildMarkdownLinkShareInfo on top of the same formatMarkdownLink logic.
  • baanish/agent-render#13: Both PRs modify src/components/home/link-creator.tsx's clipboard-copy behavior—main PR adds clipboard copying for markdownLink with length/warning UI, while the retrieved PR refactors the existing copy-to-clipboard helper.

Poem

🐇 A markdown link, so long and wide,
Discord said "2000 chars — can't abide!"
Now warnings appear with a gentle nudge,
"Split your message!" — the bunny won't budge.
Check discordMarkdownLinkWarning before you send,
And share your links safely, right to the end! 🔗✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and concisely describes the main feature added: Discord markdown link length warning detection for agents, which is the primary focus across all changed files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/discord-markdown-link-warning-aa2e

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 20, 2026

Copy link
Copy Markdown

Deploying agent-render with  Cloudflare Pages  Cloudflare Pages

Latest commit: 2530695
Status: ✅  Deploy successful!
Preview URL: https://437b29b4.agent-render.pages.dev
Branch Preview URL: https://cursor-discord-markdown-link.agent-render.pages.dev

View logs

Clarify in the agent skill that createGeneratedArtifactLink* returns a
ready-to-paste markdownLink string. Expose it in the link creator with a
dedicated copy action.

Co-authored-by: Aanish Bhirud <baanish@users.noreply.github.com>
@baanish
baanish marked this pull request as ready for review June 20, 2026 05:52

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/markdown-link.test.ts (1)

37-52: ⚡ Quick win

Add an exact-limit boundary test (== 2,000) for regression safety.

Current coverage checks “over” and “well under” the limit, but not the exact boundary where > vs >= regressions usually happen.

Suggested test addition
+  it("does not warn when markdown link length is exactly Discord's limit", () => {
+    const label = "R";
+    const prefix = `[${label}](https://example.com/#`;
+    const suffix = ")";
+    const payloadLength = DISCORD_MESSAGE_MAX_LENGTH - (prefix.length + suffix.length);
+    const href = `https://example.com/#${"a".repeat(payloadLength)}`;
+    const markdownLink = formatMarkdownLink(label, href);
+
+    expect(markdownLink.length).toBe(DISCORD_MESSAGE_MAX_LENGTH);
+    expect(isDiscordMarkdownLinkTooLong(markdownLink)).toBe(false);
+    expect(getDiscordMarkdownLinkWarning(markdownLink)).toBeNull();
+  });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/markdown-link.test.ts` around lines 37 - 52, Add a new test case that
checks the exact boundary condition when a markdown link is precisely 2,000
characters (the exact value of DISCORD_MESSAGE_MAX_LENGTH). This test should
create a markdown link using formatMarkdownLink or buildMarkdownLinkShareInfo
that results in exactly DISCORD_MESSAGE_MAX_LENGTH characters and verify the
behavior of isDiscordMarkdownLinkTooLong and getDiscordMarkdownLinkWarning at
this critical boundary. This boundary test is essential to catch off-by-one
regressions where incorrect comparison operators (> vs >=) could cause the limit
check to fail unexpectedly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/home/link-creator.tsx`:
- Around line 183-195: The handleCopyMarkdownLink function has a race condition
where the async copyTextToClipboard call can complete after generatedLink has
been replaced by a newer generation, causing stale state updates. To fix this,
capture the current generatedLink value at the start of the async operation,
then after the copy operation completes (in both success and error cases),
verify that generatedLink still matches the captured value before calling
setMarkdownLinkCopyState. Only update the state if the value hasn't changed,
ensuring the copy status reflects the actual current link.

---

Nitpick comments:
In `@tests/markdown-link.test.ts`:
- Around line 37-52: Add a new test case that checks the exact boundary
condition when a markdown link is precisely 2,000 characters (the exact value of
DISCORD_MESSAGE_MAX_LENGTH). This test should create a markdown link using
formatMarkdownLink or buildMarkdownLinkShareInfo that results in exactly
DISCORD_MESSAGE_MAX_LENGTH characters and verify the behavior of
isDiscordMarkdownLinkTooLong and getDiscordMarkdownLinkWarning at this critical
boundary. This boundary test is essential to catch off-by-one regressions where
incorrect comparison operators (> vs >=) could cause the limit check to fail
unexpectedly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1989b674-49a3-404e-8b14-e1a8ff55ee7c

📥 Commits

Reviewing files that changed from the base of the PR and between cc8c8ff and 4c17ffe.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (12)
  • AGENTS.md
  • docs/payload-format.md
  • public/.well-known/agent-skills/index.json
  • skills/agent-render-linking/SKILL.md
  • src/app/globals.css
  • src/components/home/link-creator.tsx
  • src/components/viewer/artifact-stage.tsx
  • src/lib/markdown-link.ts
  • src/lib/payload/link-creator.ts
  • tests/components/link-creator.test.tsx
  • tests/link-creator.test.ts
  • tests/markdown-link.test.ts

Comment thread src/components/home/link-creator.tsx
@kilo-code-bot

kilo-code-bot Bot commented Jun 20, 2026

Copy link
Copy Markdown

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Incremental review — 1 new commit since prior pass

Reviewed the incremental diff since the prior review at 4c17ffe. The new commit ("Address review feedback on Discord markdown link warnings") resolves the stale-closure concern in the markdown-link copy handler by mirroring generatedLink into a ref and guarding the async setMarkdownLinkCopyState calls with a copy-token + hash comparison — matching the existing pattern in handleArtifactCopy. It also adds a separate viewer-facing Discord notice (omits the agent-only "split the bundle" guidance) for the read-only artifact stage, and consolidates the Intl.NumberFormat into a single module-level instance shared by the warning/notice builders.

Verified: GeneratedArtifactLink.hash exists on the type (src/lib/payload/link-creator.ts:30), so the new link.hash / generatedLinkRef.current?.hash reads are type-safe; the viewer notice and agent warning share the same isDiscordMarkdownLinkTooLong threshold; the agent-facing creator still uses discordMarkdownLinkWarning (split guidance) while only the read-only viewer uses the softer notice — separation is clean with no dangling references; new test covers the viewer notice copy.

Static review only (typecheck/lint not run in read-only review mode).

Files Reviewed (4 files, incremental)
  • src/lib/markdown-link.ts — added getDiscordMarkdownLinkViewerNotice; shared discordNumberFormatter
  • src/components/viewer/artifact-stage.tsx — viewer notice wired into memo + warning banner
  • src/components/home/link-creator.tsx — ref + token guard for markdown-link copy; metric label fix
  • tests/markdown-link.test.ts — viewer notice test
Prior pass — unchanged files carried forward (No Issues)
  • src/app/globals.css
  • tests/link-creator.test.ts
  • tests/components/link-creator.test.tsx
  • AGENTS.md
  • docs/payload-format.md
  • skills/agent-render-linking/SKILL.md
  • public/.well-known/agent-skills/index.json
Previous Review Summary (commit 4c17ffe)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 4c17ffe)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (12 files)
  • src/lib/markdown-link.ts — new DISCORD_MESSAGE_MAX_LENGTH, buildMarkdownLinkShareInfo, and warning helpers
  • src/lib/payload/link-creator.tsmarkdownLink/markdownLinkLength/discordMarkdownLinkWarning added to GeneratedArtifactLink (sync + async)
  • src/components/home/link-creator.tsx — markdown link textarea, length metric, warning display, and copy button
  • src/components/viewer/artifact-stage.tsxpageHref effect, markdownLinkShareInfo memo, and warning banner
  • src/app/globals.css.artifact-share-warning and .creator-warning-state styles (all CSS variables verified defined)
  • tests/markdown-link.test.ts
  • tests/link-creator.test.ts
  • tests/components/link-creator.test.tsx
  • AGENTS.md
  • docs/payload-format.md
  • skills/agent-render-linking/SKILL.md
  • public/.well-known/agent-skills/index.json (digest refresh)

package-lock.json was skipped as a generated lock file per review policy.

Notes

  • The Discord limit boundary uses > 2000, so a link of exactly 2000 chars is treated as valid — correct against Discord's per-message limit.
  • The handleCopyMarkdownLink dependency change from [] to [markdownLinkShareInfo] correctly tracks the new memo and avoids a stale closure; the ?? buildMarkdownLinkShareInfo(...) fallback keeps the pre-effect (first-render) path safe.
  • All user-controlled label content is rendered through React-escaped textareas/paragraphs, so no new XSS surface is introduced; the warning string itself is a hardcoded template.
  • Docs, SKILL, and AGENTS wording aligns with the code semantics (the remaining 1,500 chars reference in SKILL.md is an unrelated budget-mode example, not a stale Discord figure).

Reviewed by GLM-5.2 · Input: 86.4K · Output: 11.6K · Cached: 172.5K

@greptile-apps

greptile-apps Bot commented Jun 20, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds Discord markdown-link length warnings throughout the agent-render sharing workflow. When a formatted [label](url) link exceeds Discord's 2,000-character message limit, the link creator, viewer toolbar, and agent-facing helpers all surface distinct, contextually appropriate notices.

  • New src/lib/markdown-link.ts helpers (buildMarkdownLinkShareInfo, getDiscordMarkdownLinkWarning, getDiscordMarkdownLinkViewerNotice, isDiscordMarkdownLinkTooLong) centralise length checking and produce separate agent-directed vs. viewer-directed copy, with an Intl.NumberFormat formatter for locale consistency.
  • GeneratedArtifactLink is extended with markdownLink, markdownLinkLength, and discordMarkdownLinkWarning; both sync and async link-creator helpers populate these fields.
  • Link creator UI gains a markdown-link textarea, a "Markdown link length" metric card, a concurrency-safe "Copy markdown link" button, and an in-place warning banner; artifact-stage viewer gains a separate viewer-notice paragraph using getDiscordMarkdownLinkViewerNotice (actionable advice removed for end users).

Confidence Score: 5/5

Safe to merge — changes are additive, well-tested, and all three concerns raised in the previous review round have been addressed.

The Discord length-check logic is straightforward and isolated in the new helpers. The viewer and link creator each use contextually appropriate copy (viewer notice vs. agent-directed warning). The Intl.NumberFormat formatter is used throughout for locale consistency. Concurrency tokens in the new copy handler are correct. Tests cover both over-limit and under-limit paths and verify the viewer notice omits split-bundle guidance. No pre-existing behaviour is altered.

No files require special attention.

Important Files Changed

Filename Overview
src/lib/markdown-link.ts Core new helpers for markdown link formatting and Discord length checks; uses Intl.NumberFormat for locale-safe number formatting, provides separate agent-facing vs viewer-facing warning strings.
src/lib/payload/link-creator.ts Adds markdownLink, markdownLinkLength, and discordMarkdownLinkWarning to GeneratedArtifactLink; both createGeneratedArtifactLink and createGeneratedArtifactLinkAsync correctly populate these via buildGeneratedLinkShareInfo.
src/components/home/link-creator.tsx Adds markdown-link textarea, length metric card, concurrency-safe copy button, and warning banner; copy state management consistent with existing handleCopy pattern.
src/components/viewer/artifact-stage.tsx Uses pageHref state (SSR-safe, set in useEffect) and memoized markdownLinkShareInfo to show a viewer-appropriate Discord notice; copy handler falls back to window.location.href when state not yet populated.
src/app/globals.css Adds .artifact-share-warning and .creator-warning-state styles using --warning CSS variable and color-mix; mirrors existing .creator-error-state pattern.
tests/markdown-link.test.ts Good coverage: tests both over-limit and under-limit paths, verifies viewer notice does not contain split-bundle guidance, and checks buildMarkdownLinkShareInfo output shape.
tests/link-creator.test.ts Adds test for the Discord warning surface path via createGeneratedArtifactLinkAsync with a 2800-char payload; asserts markdownLinkLength, warning text, and multi-message guidance.
skills/agent-render-linking/SKILL.md Updated with ready-to-send markdown link guidance, markdownLinkLength/discordMarkdownLinkWarning fields, and revised Discord limit from 1,500 to 2,000 characters.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[createGeneratedArtifactLink / Async] --> B[buildGeneratedLinkShareInfo\nlabel from envelope.title]
    B --> C[buildMarkdownLinkShareInfo\nformatMarkdownLink + length check]
    C --> D{markdownLink.length\n> 2000?}
    D -->|No| E[discordMarkdownLinkWarning: null]
    D -->|Yes| F[getDiscordMarkdownLinkWarning\nagent-directed split-bundle advice]
    E --> G[GeneratedArtifactLink\nmarkdownLink / markdownLinkLength / discordMarkdownLinkWarning]
    F --> G
    G --> H[LinkCreator UI\nwarning banner + copy button]

    I[ArtifactStage viewer] --> J[buildMarkdownLinkShareInfo\nactiveArtifactHeading + pageHref]
    J --> K{markdownLink.length\n> 2000?}
    K -->|No| L[discordViewerNotice: null]
    K -->|Yes| M[getDiscordMarkdownLinkViewerNotice\nviewer-facing may be too long notice]
    L --> N[No warning shown]
    M --> O[artifact-share-warning paragraph]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[createGeneratedArtifactLink / Async] --> B[buildGeneratedLinkShareInfo\nlabel from envelope.title]
    B --> C[buildMarkdownLinkShareInfo\nformatMarkdownLink + length check]
    C --> D{markdownLink.length\n> 2000?}
    D -->|No| E[discordMarkdownLinkWarning: null]
    D -->|Yes| F[getDiscordMarkdownLinkWarning\nagent-directed split-bundle advice]
    E --> G[GeneratedArtifactLink\nmarkdownLink / markdownLinkLength / discordMarkdownLinkWarning]
    F --> G
    G --> H[LinkCreator UI\nwarning banner + copy button]

    I[ArtifactStage viewer] --> J[buildMarkdownLinkShareInfo\nactiveArtifactHeading + pageHref]
    J --> K{markdownLink.length\n> 2000?}
    K -->|No| L[discordViewerNotice: null]
    K -->|Yes| M[getDiscordMarkdownLinkViewerNotice\nviewer-facing may be too long notice]
    L --> N[No warning shown]
    M --> O[artifact-share-warning paragraph]
Loading

Reviews (2): Last reviewed commit: "Address review feedback on Discord markd..." | Re-trigger Greptile

Comment thread src/components/home/link-creator.tsx
Comment thread src/components/viewer/artifact-stage.tsx Outdated
Comment thread src/lib/markdown-link.ts Outdated
- Guard markdown-link copy against stale async completion
- Use viewer-facing notice copy in artifact stage
- Format warning numbers with Intl.NumberFormat
- Rename duplicate metric label to Markdown link length

Co-authored-by: Aanish Bhirud <baanish@users.noreply.github.com>
@baanish
baanish merged commit ec069cf into main Jun 20, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants